仍在与这个 shell 脚本(密码验证)作斗争,我已经寻找解决方案,但我仍然找不到正确的解决方案。
#!/bin/sh
echo "enter the password"
read password
len="${#password}"
if test $len -ge 8 ; then
echo "$password" | grep -q [A-Z]
echo "$password" | grep -q [a-z]
echo "$password" | grep -q [0-9]
if test $? -eq 0 ; then
echo "Strong password"
else
echo "Weak password"
fi
else
echo "password lenght should be greater than or equal 8"
fi
该脚本的结果如下:
# ./password.sh
enter the password
12345678
Strong password >> Not as I expected which is should be weak password
我的错在哪里?
答案1
一些东西:
使用
read
without会使密码-r
变得困难。\
不引用正则表达式将使 shell 将它们视为通配模式,并且它们将扩展为文件名。
该
$?
变量将仅保存最后一个的退出状态grep
。
考虑以下bash
脚本:
#!/bin/bash
read -r -p "password:" -s password
if (( ${#password} < 8 )); then
echo "Passwords need 8 or more characters"
exit 1
fi
has_upcase=0
has_locase=0
has_digit=0
has_other=0
case "$password" in
*[[:upper:]]*) has_upcase=1 ;;&
*[[:lower:]]*) has_locase=1 ;;&
*[[:digit:]]*) has_digit=1 ;;&
*[^[:alnum:]]*) has_other=1 ;;
esac
if (( !has_upcase )); then
echo "Make sure you password has at least one upper-case letter"
elif (( !has_locase )); then
echo "Make sure your password has at least one lower-case letter"
elif (( !has_digit )); then
echo "Make sure your password has at least one digit"
elif (( !has_other )); then
echo "Make sure your password has at least non-alphanumeric character"
else
echo "Your password is ok"
fi
我冒昧地在测试中添加了“非字母数字”要求。
of能够向用户提供提示,并在不回显键入内容的情况下进行阅读read
。bash
该case
语句检查输入的密码是否至少包含 1 个大写字母、1 个小写字母、1 个数字和 1 个非字母数字字符(使用POSIX 字符类)。;;&
每行末尾的时髦外观意味着“继续使用该字符串测试下一个模式”。
要获得sh
它的 POSIX 变体,请将其替换read
为
stty -echo
printf "password: "
read -r password
stty echo
printf "\n"
以及case
类似的声明
case "$password" in *[[:upper:]]*) has_upcase=1 ;; esac
case "$password" in *[[:lower:]]*) has_locase=1 ;; esac
case "$password" in *[[:digit:]]*) has_digit=1 ;; esac
case "$password" in *[^[:alnum:]]*) has_other=1 ;; esac
其余的应该还是POSIX。
答案2
您的grep
调用将按顺序运行,并且$?
仅等于grep
脚本中的最后一个调用。你会想在每个之后使用类似的东西grep
:
retCodes=0
echo "$password" | grep -q "[A-Z]"
retCodes=$(($retCodes + $?))
echo "$password" | grep -q "[a-z]"
retCodes=$(($retCodes + $?))
echo "$password" | grep -q "[0-9]"
retCodes=$(($retCodes + $?))
这if [[ $retCodes -eq 0 ]]; then ...
答案3
也许这会有所帮助:
#!/bin/sh
echo "enter the password"
read -r password
caps="$(echo "$password" | sed 's/[^A-Z]//g')"
lowers="$(echo "$password" | sed 's/[^a-z]//g')"
numbers="$(echo "$password" | sed 's/[^0-9]//g')"
if [ "${#password}" -lt 8 ]; then
echo "password lenght should be greater than or equal 8"
else
echo "caps=${#caps} lowers=${#lowers} numbers=${#numbers}"
if [ "${#caps}" -ge 1 ] && [ "${#lowers}" -ge 1 ] && [ "${#numbers}" -ge 1 ]; then
echo "Strong password"
else
echo "Weak password"
fi
fi