在符合POSIX的外壳中要求输入密码?


Answers:


24
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"
  )"
}

请注意,对于printf未内置的那些shell(mksh),ps如果对所有命令调用及其参数进行了审核,则密码将在输出中清晰显示(几秒钟),或在某些审核日志中显示。


2
可能cat+ Heredoc可以更安全地替代printf吗?
约翰·库格曼

1
@JohnKugelman这里的文档在大多数shell中都是作为临时文件编写的,而printf是在大多数shell中构建的。我不确定哪个最好。
斯特凡Chazelas


感谢您展示如何保存和还原旧stty设置。
Barmar

20

read -s不在POSIX中。如果要兼容POSIX,请使用stty -echostty及其echo参数在POSIX中定义。

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

这将在所有符合POSIX的shell上工作。

资源


7
为了突出显示@ arkadiusz-drabczyk注释中答案的要点,最好捕获所有可以打开的信号,以便重新打开stty echo-以防用户感到困惑并在本read PASSWORD节中碰到control-C 。
杰夫·谢勒

在该主题中阅读链接的答案或查看Stephane的答案
Jeff Schaller

您不应无条件打开回显,而应保存并恢复旧设置。许多人在Emacs Shell缓冲区中工作,并且通常禁用回显,因为Emacs自己在做回显。另一个答案显示了如何执行此操作。
Barmar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.