在 POSIX 兼容的 shell 中询问密码?

在 POSIX 兼容的 shell 中询问密码?

当我想在脚本中请求密码时bash,我会这样做:

read -s

...但是当我bash在 POSIX 模式下运行时,使用sh,该-s选项被拒绝:

$ read -s
sh: 1: read: Illegal option -s

如何使用符合 POSIX 标准的命令安全地请求输入?

答案1

read_password() {
  REPLY="$(
    # always read from the tty even when redirected:
    exec < /dev/tty || exit # || exit only needed for bash

    # save current tty settings:
    tty_settings=$(stty -g) || exit

    # schedule restore of the settings on exit of that subshell
    # or on receiving SIGINT or SIGTERM:
    trap 'stty "$tty_settings"' EXIT INT TERM

    # disable terminal local echo
    stty -echo || exit

    # prompt on tty
    printf "Password: " > /dev/tty

    # read password as one line, record exit status
    IFS= read -r password; ret=$?

    # display a newline to visually acknowledge the entered password
    echo > /dev/tty

    # return the password for $REPLY
    printf '%s\n' "$password"
    exit "$ret"
  )"
}

请注意,对于那些非内置 shell(ksh88、mksh 和大多数其他 pdksh 派生 shell),printf密码将在ps输出中以明文形式显示(几微秒),或者如果所有命令调用都使用他们的参数经过审核。但是,在这些 shell 中,您可以将其替换为print -r -- "$password".

任何状况之下echo通常不是一个选择

另一种符合 POSIX 标准的不涉及在输出中泄露密码ps(但最终可能会将其写入永久存储)的方法是:

cat << EOF
$password
EOF

另请注意,zshIFS= read -rs 'pass?Password: '或 bash会在 stderr 上IFS= read -rsp 'Password: ' pass发出提示。Password:因此,对于这些,您可能需要添加一个2> /dev/tty以确保提示符转到控制终端。

任何状况之下,确保你不要忘记IFS=-r

答案2

read -s不在 POSIX 中。如果您想符合 POSIX 标准,请使用stty -echo.stty及其echo参数是在 POSIX 中定义的。

#!/bin/bash
stty -echo
printf "Password: "
read PASSWORD
stty echo
printf "\n"

这适用于所有符合 POSIX 的 shell。

来源

相关内容