需要帮助编写 bash 脚本,该脚本使用正则表达式来验证密码输入是否满足长度和特殊字符要求

需要帮助编写 bash 脚本,该脚本使用正则表达式来验证密码输入是否满足长度和特殊字符要求

我已经为此工作了一段时间,访问了数十个网站并尝试了各种组合;但是,我无法让脚本按预期运行。即使他们工作在https://regex101.com/,我仍然无法让它们在 bash 中工作。

我正在尝试编写一个 bash 脚本,该脚本将验证输入(“$password”)的长度至少为八个字符,并且至少包含一个数字和至少一个以下特殊字符:#?!@$ %^&* -

GNU bash,版本 5.1.16(1)-release-(x86_64-pc-linux-gnu)

任何帮助将不胜感激!

read -p "Please enter a password to test: " password
echo "You entered '$password'"
# I have tried all of the following (plus a few others) and cannot get it to work
#regex='^[a-zA-Z0-9#@$?]{8,}$'
#regex='^[a-zA-Z0-9@#$%&*+-=]{8,}$'
#regex='^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[@#$%&*+-=]).{8,}$'
#regex='^(?=.*?[a-zA-Z0-9])(?=.*?[#?!@$ %^&*-]).{8,}$'
#regex='^(?=.*[A-Za-z])(?=.*[0-9])(?=.*[#?!@$ %^&*-]).{8,}$'
if [[ $password =~ $regex ]]; then
        echo "This works"
else
        echo "Nope"
fi

答案1

支持的扩展正则表达式语法bash缺乏构造在多个子表达式之间执行布尔 AND 测试的单个表达式的能力。因此,您可以更轻松地对每种条件执行一次测试。

您的字符串似乎需要满足三个条件:

  1. 至少八个字符。
  2. 至少一位数字(我认为您所说的“数字”就是这个意思)。
  3. 该组中至少有一个角色#?!@$ %^&*-

这意味着三个测试:

if [ "${#password}" -ge 8 ] &&
   [[ $password == *[[:digit:]]* ]] &&
   [[ $password == *[#?!@$\ %^\&*-]* ]]
then
    echo 'good'
else
    echo 'not good'
fi

在最后的测试中,一些特殊字符必须被转义。我们可以通过使用变量让它看起来更漂亮:

has_digit='*[[:digit:]]*'
has_special='*[#?!@$ %^&*-]*'  # or possibly '*[[:punct:]]*'

if [ "${#password}" -ge 8 ] &&
   [[ $password == $has_digit ]] &&
   [[ $password == $has_special ]]
then
    echo 'good'
else
    echo 'not good'
fi

请注意,我在这里没有使用正则表达式,而是使用普通的 shell 模式。匹配的集合[[:punct:]]是稍大的“标点符号”集合(特别不包含空格字符,但您可以使用[[:punct:] ]or[[:punct:][:blank:]][[:punct:][:space:]]):

!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

如果您确实只需要使用正则表达式,那么请执行以下操作

has_8='.{8}'
has_digit='[[:digit:]]'
has_special='[#?!@$ %^&*-]'  # or possibly '[[:punct:]]'

if [[ $password =~ $has_8 ]] &&
   [[ $password =~ $has_digit ]] &&
   [[ $password =~ $has_special ]]
then
    echo 'good'
else
    echo 'not good'
fi

注意改变的模式。


关于该站点的一般警告regex101.com是,它并未声称专门支持大多数标准 Unix 文本处理工具使用的 POSIX 正则表达式,而仅支持这些正则表达式的各种扩展变体。

答案2

作为一个选项:

if [ ! "${password/????????*}" -a\ 
        "$password" != "${password/[0-9]}" -a\ 
        "$password" != "${password/[#?!@$ %^&*-]}" ]
then
        echo "This works"
else
        echo "Nope"
fi

但据我记得,验证提供了小写和大写字母的存在,这意味着您需要更改:

if [ ! "${password/????????*}" -a\ 
        "$password" != "${password/[a-z]}" -a\ 
        "$password" != "${password/[A-Z]}" -a\ 
        "$password" != "${password/[0-9]}" -a\ 
        "$password" != "${password/[#?!@$ %^&*-]}" ]

相关内容