You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 14:07:44