bash 使用“read”读取密码时如何回显星号(*)?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1923435/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 18:47:58  来源:igfitidea点击:

How do I echo stars (*) when reading password with `read`?

bashshellpasswords

提问by Deniz Zoeteman

What do I need to do for code in Bash, if I want to echo *s in place of password characters (or even just hide the characters completely) when the user types something in using read?

如果我想*在用户键入内容时使用echo代替密码字符(甚至只是完全隐藏字符),我需要为 Bash 中的代码做什么read

回答by Paused until further notice.

As Mark Rushakoffpointed out, read -swill suppress the echoing of characters typed at the prompt. You can make use of that feature as part of this script to echo asterisks for each character typed:

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

#!/bin/bash
unset password
prompt="Enter Password:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
    if [[ $char == $'
#!/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 == $'
-s     Silent mode.  If input is coming from a terminal, characters are not echoed.
' ]] ; then break fi # Backspace if [[ $CHAR == $'7' ]] ; 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
' ]] then break fi prompt='*' password+="$char" done echo echo "Done. Password=$password"

回答by Logan VanCuren

I really liked the answer that Wironegave, but I didn't like that the backspacing would continue removing characters even back into the "Enter password: " prompt.

我真的很喜欢Wirone给出的答案,但我不喜欢退格会继续删除字符,即使回到“输入密码:”提示。

I also had some issues where pressing keys too rapidly would cause some of the characters to actually print on the screen... never a good thing when prompting for a password. =)

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

The following is my modified version of Wirone's answer which addresses these issues:

以下是我解决这些问题的Wirone答案的修改版本:

#!/bin/bash

unset password
echo -n "Enter password: "
while IFS= read -p "$prompt" -r -s -n 1 char
do
    # Enter - accept password
    if [[ $char == $'
 #!/bin/sh 
 read -p "Username: " uname 
 stty -echo 
 read -p "Password: " passw; echo 
 stty echo
' ]] ; then break fi # Backspace if [[ $char == $'7' ]] ; then prompt=$'\b \b' password="${password%?}" else prompt='*' password+="$char" fi done

回答by Mark Rushakoff

read -sshould put it in silent mode:

read -s应该将其置于静音模式:

stty -echo
read something
stty echo

See the readsection in man bash.

请参阅 中的read部分man bash

回答by Wirone

I would like to add something to Dennis Williamson's solution:

我想在Dennis Williamson的解决方案中添加一些内容:

read -s pass
echo "$pass" | sed 's/./*/g'

In above example script handles backspace correctly.

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

Source

来源

回答by Vinko Vrsalovic

I don't know about stars, but stty -echo is your friend:

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

ask() {
  local 'args' 'char' 'charcount' 'prompt' 'reply' 'silent'

  # Basic arguments parsing
  while [[ "${1++}" ]]; do
    case "" in
      ( '--silent' | '-s' )
        silent='yes'
        ;;
      ( '--' )
        args+=( "${@:2}" )
        break
        ;;
      ( * )
        args+=( "" )
        ;;
    esac
    shift || break
  done

  if [[ "${silent}" == 'yes' ]]; then
    for prompt in "${args[@]}"; do
      charcount='0'
      prompt="${prompt}: "
      reply=''
      while IFS='' read -n '1' -p "${prompt}" -r -s 'char'; do
        case "${char}" in
          # Handles NULL
          ( $'
$ ask Username
Username: AzureDiamond
AzureDiamond

$ ask -s Password
Password: *******
hunter2

$ ask First Second Third
First: foo
foo
Second: bar
bar
Third: baz
baz
0' ) break ;; # Handles BACKSPACE and DELETE ( $'0' | $'7' ) if (( charcount > 0 )); then prompt=$'\b \b' reply="${reply%?}" (( charcount-- )) else prompt='' fi ;; ( * ) prompt='*' reply+="${char}" (( charcount++ )) ;; esac done printf '\n' >&2 printf '%s\n' "${reply}" done else for prompt in "${args[@]}"; do IFS='' read -p "${prompt}: " -r 'reply' printf '%s\n' "${reply}" done fi }

Source: http://www.peterbe.com/plog/passwords-with-bash

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

回答by moonshadow

#!/bin/bash
echo "------------------------------"

n=7
echo " Enter Password :"

for (( i=1;i<n;i++ ))
do
    stty -echo
    read -r -s -n 1 char
    stty echo

    echo -n "*"
    pass+="$char"

done

echo " "
echo " Your password : $pass "

echo ""
echo "-------------------------------"

will stop user input being echoed to the screen for that read. Depending on what you are doing with prompts, you may want to add an extra echocommand to generate a newline after the read.

将停止将用户输入回显到该读取的屏幕上。根据您对提示所做的操作,您可能需要添加一个额外的echo命令以在读取后生成换行符。

回答by Dino Dini

If you don't care about it being interactive, you can simply do

如果你不关心它的交互性,你可以简单地做

##代码##

This will show a * for each character of the entered password after enter is pressed.

按下回车键后,这将为输入的密码的每个字符显示一个 *。

回答by nxnev

I just made this Bash-specific function based on Dennis Williamson's, Wirone's and Logan VanCuren's answers:

我刚刚根据Dennis Williamson的、Wirone的和Logan VanCuren的回答制作了这个 Bash 特定的函数:

##代码##

It could be used like:

它可以像这样使用:

##代码##

回答by 7in

##代码##