Linux Shell脚本密码验证问题:大小写及特殊字符校验失效
Shell密码验证脚本:大小写与特殊字符校验失效排查方案
核心失效原因及排查要点
正则表达式元字符未正确处理
规则中的特殊字符#$&~@^里,^在正则字符集开头会变成否定匹配(比如[^abc]表示不包含abc),$是行尾锚定符,这些都需要转义才能匹配字面字符。如果你的正则写的是[#$&~@^],要么^在开头导致逻辑完全反转,要么$被解析为锚定,根本匹配不到$字符。正确写法应为[\#\$\&\~\@\^]。正则匹配时错误使用引号
Shell中用[[ $var =~ 正则 ]]时,给正则加引号会让它变成普通字符串匹配,而非正则解析。比如[[ $password =~ "[A-Z]" ]]会匹配字面的[A-Z]字符串,而不是任何大写字母。必须去掉正则的引号。文件读取方式导致密码截断
如果用for password in $(cat emppw.txt)读取文件,Shell会把空格、制表符作为分隔符拆分内容,导致带空格的密码被拆成多个部分,校验自然失效。正确要用while read -r password循环读取,保留完整行内容。特殊字符被Shell解析修改
密码中的$会被Shell当作变量解析,比如密码Pass$word12#会被替换成Pass(如果word12#变量不存在)。用read -r可以避免反斜杠转义,同时读取文件时直接通过重定向输入,不会触发变量解析。
修正后的校验脚本示例
#!/bin/bash # 定义各校验规则的正则 readonly UPPER_REGEX='[A-Z]' readonly LOWER_REGEX='[a-z]' readonly DIGIT_REGEX='[0-9]' readonly SPECIAL_REGEX='[\#\$\&\~\@\^]' # 逐行读取密码文件 while read -r pw; do # 跳过空行 [[ -z "$pw" ]] && continue # 长度校验 if [[ ${#pw} -lt 10 ]]; then echo "不符合要求: '$pw' - 长度不足10位" continue fi # 大写字母校验 if ! [[ $pw =~ $UPPER_REGEX ]]; then echo "不符合要求: '$pw' - 缺少大写字母" continue fi # 小写字母校验 if ! [[ $pw =~ $LOWER_REGEX ]]; then echo "不符合要求: '$pw' - 缺少小写字母" continue fi # 数字校验 if ! [[ $pw =~ $DIGIT_REGEX ]]; then echo "不符合要求: '$pw' - 缺少数字" continue fi # 特殊字符校验 if ! [[ $pw =~ $SPECIAL_REGEX ]]; then echo "不符合要求: '$pw' - 缺少指定特殊字符(#\$&~@^)" continue fi echo "符合要求: '$pw'" done < emppw.txt
快速调试技巧
- 在校验前加
echo "当前校验内容: '$pw'",确认读取的密码和文件中完全一致,没有被截断或修改。 - 用
echo "Test123Ab#" | grep -qE "$SPECIAL_REGEX" && echo 匹配成功 || echo 匹配失败单独测试正则是否能正常工作。
内容的提问来源于stack exchange,提问作者kingsport
相关产品推荐
相关产品推荐

