使用`read`读密码时如何回显星号(*)?

Den*_*man 37 passwords bash shell

如果我想在用户输入内容时用回声*代替密码字符(甚至只是隐藏字符),我需要对Bash中的代码做什么read

Pau*_*ce. 58

正如Mark Rushakoff指出的那样,read -s将抑制在提示符下键入的字符的回显.您可以将此功能用作此脚本的一部分,以便为每个键入的字符回显星号:

#!/bin/bash
unset password
prompt="Enter Password:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
    if [[ $char == $'\0' ]]
    then
        break
    fi
    prompt='*'
    password+="$char"
done
echo
echo "Done. Password=$password"
Run Code Online (Sandbox Code Playgroud)

  • 您需要"取消设置IFS"或将"IFS ="添加到while循环中,否则您的循环将过早地破坏包含空格的密码.此外,您应该将`-r`标志添加到`read`,以便密码可以包含反斜杠. (5认同)
  • @BradMace:您不能使用Bash,ksh(93)或zsh,或者您使用的是旧版本的Bash(例如2.05b). (2认同)

小智 19

我真的很喜欢Wirone给出的答案,但我不喜欢退格会继续删除字符甚至回到"输入密码:"提示符.

我也有一些问题,按键太快会导致一些字符实际打印在屏幕上...提示输入密码时从来都不是一件好事.=)

以下是我修改的Wirone的答案,它解决了这些问题:

#!/bin/bash

unset PASSWORD
unset CHARCOUNT

echo -n "Enter password: "

stty -echo

CHARCOUNT=0
while IFS= read -p "$PROMPT" -r -s -n 1 CHAR
do
    # Enter - accept password
    if [[ $CHAR == $'\0' ]] ; then
        break
    fi
    # Backspace
    if [[ $CHAR == $'\177' ]] ; then
        if [ $CHARCOUNT -gt 0 ] ; then
            CHARCOUNT=$((CHARCOUNT-1))
            PROMPT=$'\b \b'
            PASSWORD="${PASSWORD%?}"
        else
            PROMPT=''
        fi
    else
        CHARCOUNT=$((CHARCOUNT+1))
        PROMPT='*'
        PASSWORD+="$CHAR"
    fi
done

stty echo

echo $PASSWORD
Run Code Online (Sandbox Code Playgroud)


Mar*_*off 12

read -s 应该把它放在静音模式:

-s     Silent mode.  If input is coming from a terminal, characters are not echoed.
Run Code Online (Sandbox Code Playgroud)

请参阅中的read部分man bash.

  • 他想要一些反馈,而不是无声的沉默! (2认同)

Wir*_*one 6

我想补充丹尼斯威廉姆森的解决方案:

#!/bin/bash

unset password
echo -n "Enter password: "
while IFS= read -p "$prompt" -r -s -n 1 char
do
    # Enter - accept password
    if [[ $char == $'\0' ]] ; then
        break
    fi
    # Backspace
    if [[ $char == $'\177' ]] ; then
        prompt=$'\b \b'
        password="${password%?}"
    else
        prompt='*'
        password+="$char"
    fi
done
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,脚本正确处理退格.

资源

  • Ctrl-H*是*退格(Unicode标准称之为`BACKSPACE`).`$'\ 177'`是DEL(Unicode称它为'DELETE`).某些终端程序可以选择将Backspace键映射到DEL字符,但许多"*normal*"用户(包括我自己)将其映射到退格键(Ctrl-H).一个强大的解决方案将检查用户的tty设置. (2认同)
  • Dude,*my*键盘上的退格键发送ASCII BS字符(8),*不是*ASCII DEL字符(127).我的tty设置是这样的,键入backspace删除光标前的字符.它是可配置的,并且您的代码假定特定的配置不是通用的.我的设置没有任何非标准或异常,您的代码将无法正常使用它. (2认同)

Vin*_*vic 5

我不知道星星,但stty -echo是你的朋友:

 #!/bin/sh 
 read -p "Username: " uname 
 stty -echo 
 read -p "Password: " passw; echo 
 stty echo
Run Code Online (Sandbox Code Playgroud)

资料来源:http://www.peterbe.com/plog/passwords-with-bash

  • 这似乎没有必要,因为 `read` 有一个 `-s` 选项(问题被标记为 `bash`,因此我们可以假设 bash 特定的功能)。中断 `read` 命令(例如,通过键入 control-C)可能会使 tty 处于 `-echo` 模式。 (2认同)