如何在Bash中实现类函数式编程?——通用密码请求函数的改造实现
通用型Bash密码请求函数实现
这是一个很实用的需求!在Bash里实现这种类函数式的通用密码请求逻辑,核心思路就是把验证逻辑抽离成独立的函数,然后将函数名作为参数传递给通用的密码请求函数。这样不同场景只需要编写对应场景的验证函数,完全复用通用的交互逻辑。
改造后的通用requestPassword函数
requestPassword() { # 第一个参数:验证函数名 local validation_func="$1" # 第二个参数:自定义提示语(默认值:Enter password:) local prompt="${2:-Enter password:}" # 第三个参数:可选的场景提示信息 local infomsg="${3:-}" local passwordValidated=false local pass errmsg while [ "$passwordValidated" = "false" ]; do # 清空终端 tput clear # 显示场景提示信息(如果有) [ -n "$infomsg" ] && echo -e "$infomsg" >&2 # 显示上一次的错误提示(如果有,用红色高亮) if [ -n "$errmsg" ]; then echo -e "\033[31mError: $errmsg\033[0m" >&2 echo >&2 fi # 静默读取密码,不显示输入内容 read -s -p "$prompt" pass >&2 echo >&2 # 手动换行,因为read -s不会自动添加换行 # 调用传入的验证函数,捕获其输出作为错误信息 errmsg="$("$validation_func" "$pass")" # 错误信息为空 → 验证通过 if [ -z "$errmsg" ]; then passwordValidated=true fi done # 输出最终验证通过的密码到stdout,方便捕获到变量中 echo "$pass" }
关键逻辑说明
- 验证函数传递:通过第一个参数接收验证函数名,用
"$validation_func" "$pass"的方式调用,捕获函数的输出作为错误信息——这完全符合你要求的「验证函数仅在失败时输出内容」的规则,输出为空就代表验证通过。 - 交互体验优化:添加了红色错误提示,清空终端避免信息混乱,手动换行解决
read -s不换行的问题。 - 灵活性:支持自定义提示语和场景信息,适配不同需求。
不同场景的验证函数示例
1. 验证系统用户密码
用于确认输入的密码是当前用户的系统登录密码:
validate_system_password() { local pass="$1" # 通过su命令验证密码正确性,静默执行 echo "$pass" | su -c true "$USER" 2>/dev/null # 验证失败时输出错误信息 if [ $? -ne 0 ]; then echo "Incorrect system password, please try again." fi }
使用方式:
# 请求并验证系统密码 system_pass=$(requestPassword validate_system_password \ "Enter your system password: " \ "Please authenticate to access the admin panel.") echo "✅ System password validated successfully."
2. 验证新密码复杂度
用于设置新密码时,检查密码是否符合复杂度要求(至少8位,包含大小写字母和数字):
validate_new_password() { local pass="$1" # 检查长度 if [ ${#pass} -lt 8 ]; then echo "Password must be at least 8 characters long." return fi # 检查大写字母 if ! [[ "$pass" =~ [A-Z] ]]; then echo "Password must contain at least one uppercase letter." return fi # 检查小写字母 if ! [[ "$pass" =~ [a-z] ]]; then echo "Password must contain at least one lowercase letter." return fi # 检查数字 if ! [[ "$pass" =~ [0-9] ]]; then echo "Password must contain at least one number." return fi # 验证通过,无输出 }
使用方式:
# 请求符合要求的新密码 new_pass=$(requestPassword validate_new_password \ "Enter new password: " \ "Create a strong password for your account.") echo "✅ New password meets complexity requirements."
3. 验证加密文件密码(以GPG为例)
用于验证输入的密码是否能解密指定的GPG加密文件:
validate_gpg_file_password() { local pass="$1" local encrypted_file="secret_docs.gpg" # 尝试静默解密,只检查返回码 echo "$pass" | gpg --batch --passphrase-fd 0 --decrypt "$encrypted_file" >/dev/null 2>&1 if [ $? -ne 0 ]; then echo "Incorrect password, failed to unlock the encrypted file." fi }
使用方式:
# 请求加密文件密码 gpg_pass=$(requestPassword validate_gpg_file_password \ "Enter GPG password: " \ "Please unlock the encrypted confidential file.") echo "✅ Encrypted file unlocked successfully."
额外注意事项
- 安全规范:不要在脚本中明文存储密码,验证完成后可以用
unset pass及时清除变量。 - 二次确认扩展:如果需要二次输入密码确认(比如设置新密码),可以写一个包装函数,调用两次
requestPassword并比对结果。 - 兼容性:确保验证函数的返回逻辑一致——仅在失败时输出内容,成功时无任何输出。
内容的提问来源于stack exchange,提问作者CraigR8806
相关产品推荐
相关产品推荐

