Bash密码强度校验脚本如何同时支持-f读文件与直接传密码参数
解决方案
实现原理
Bash的getopts处理完所有带-前缀的选项后,内置变量$OPTIND会指向第一个非选项参数的位置,我们只需要将已经处理完的选项参数从位置参数列表中移除,就能直接读取用户传入的无选项密码参数。
具体修改步骤
你只需要在原代码的while getopts循环结束后,新增如下代码即可:
# 移除所有已经处理完成的选项参数 shift $((OPTIND - 1)) # 判断是否已经通过-f选项获取到密码,未获取则读取位置参数作为密码 if [ -z "$password" ]; then # 校验用户是否传入了密码参数,未传入则提示用法 if [ $# -eq 0 ]; then echo "用法错误:请要么通过 -f 选项指定存储密码的文件,要么直接传入密码作为参数" echo "用法示例:" echo "$0 -f passwd.txt" echo "$0 MyTestPass123" exit 2 fi password="$1" fi
额外优化提示
- 原代码中初始化
requirements数组的语句是requirements=(foo bar),数组初始长度只有2,但后续代码用到了索引2的位置,会导致赋值逻辑异常,建议将该初始化语句修改为requirements=()即可正常运行。 - 原代码中读取密码文件的语句
password=cat $OPTARG``建议修改为password=$(cat "$OPTARG"),避免文件路径包含空格时读取失败。
完整修改后代码
#!/bin/bash while getopts ":f:" option; do case $option in f) password=$(cat "$OPTARG") ;; esac done # 新增功能代码开始 shift $((OPTIND - 1)) if [ -z "$password" ]; then if [ $# -eq 0 ]; then echo "用法错误:请要么通过 -f 选项指定存储密码的文件,要么直接传入密码作为参数" echo "用法示例:" echo "$0 -f passwd.txt" echo "$0 MyTestPass123" exit 2 fi password="$1" fi # 新增功能代码结束 #evaluating how much chars the password has password_length=${#password} #counter for checking in how much sections the password meets the rquirements count=0 #修正数组初始化语句 requirements=() #Checking if password includes minimum of 10 characters if [ $password_length -ge 10 ]; then requirements[0]="Correct" else requirements[0]="Incorrect password syntax. The password length must includes minimum of 10 characters" fi #checkig if the password includes both alphabet and number if [[ "$password" == *[a-zA-Z]* && "$password" == *[0-9]* ]] then requirements[1]="Correct" else requirements[1]="Incorrect password syntax. The password must includes both alphabet and number" fi #checking if password includes both the small and capital case letters. if [[ "$password" == *[A-Z]* && "$password" == *[a-z]* ]]; then requirements[2]="Correct" else requirements[2]="Incorrect password syntax. The password must includes both the small and capital case letters" fi #checking whether the password is according to the requirements or not #if yes count will equal to 3 at the end for i in "${requirements[@]}" do if [[ $i == "Correct" ]]; then let count++ fi done #if the counter count is equal to 3 print the password in light green color and return exit 0 if [[ $count -eq 3 ]]; then echo -e "\e[92m$password" # sleep - user has the time to see that the password's syntax is correct sleep 3 exit 0 #if the count is not equal to 3 print the password in reg color and return exit 1 else echo -e "\e[91m$password" for i in "${requirements[@]}" do if [[ $i != "Correct" ]]; then echo $i fi done # sleep - user has the time to see that the password's syntax is incorrect and the reasons for that sleep 6 exit 1 fi
内容的提问来源于stack exchange,提问作者Avichai Abutbul
相关产品推荐
相关产品推荐

