当用户使用{{1}键入内容时,如果我想回复*
代替密码字符(甚至只是完全隐藏字符),我需要对Bash中的代码做什么? }?
答案 0 :(得分:56)
正如 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"
答案 1 :(得分:18)
我真的很喜欢 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
答案 2 :(得分:12)
read -s
应该将其置于静音模式:
-s Silent mode. If input is coming from a terminal, characters are not echoed.
请参阅man bash
中的read
部分。
答案 3 :(得分:6)
我想在 Dennis Williamson 的解决方案中添加一些内容:
#!/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
在上面的示例中,脚本正确处理退格。
答案 4 :(得分:5)
我不知道明星,但stty -echo是你的朋友:
#!/bin/sh
read -p "Username: " uname
stty -echo
read -p "Password: " passw; echo
stty echo
答案 5 :(得分:2)
stty -echo
read something
stty echo
将阻止用户输入回显到该读取的屏幕。根据您对提示的操作,您可能需要添加额外的echo
命令以在读取后生成换行符。
答案 6 :(得分:2)
如果您不关心它是否具有互动性,您可以直接进行
read -s pass
echo "$pass" | sed 's/./*/g'
按下输入后,这将为输入密码的每个字符显示一个*。
答案 7 :(得分:1)
我刚刚根据 Dennis Williamson , Wirone 和 Logan VanCuren 的答案制作了这个特定于Bash的功能:< / p>
ask() {
local 'args' 'char' 'charcount' 'prompt' 'reply' 'silent'
# Basic arguments parsing
while [[ "${1++}" ]]; do
case "${1}" in
( '--silent' | '-s' )
silent='yes'
;;
( '--' )
args+=( "${@:2}" )
break
;;
( * )
args+=( "${1}" )
;;
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
( $'\000' )
break
;;
# Handles BACKSPACE and DELETE
( $'\010' | $'\177' )
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
}
可以像:
一样使用$ ask Username
Username: AzureDiamond
AzureDiamond
$ ask -s Password
Password: *******
hunter2
$ ask First Second Third
First: foo
foo
Second: bar
bar
Third: baz
baz
答案 8 :(得分:0)
@nxnev的answer至少在macOS上对我没有作用。我做了一点简化,现在它是完美的:
#!/bin/bash
ask() {
charcount='0'
prompt="${1}: "
reply=''
while IFS='' read -n '1' -p "${prompt}" -r -s 'char'
do
case "${char}" in
# Handles NULL
( $'\000' )
break
;;
# Handles BACKSPACE and DELETE
( $'\010' | $'\177' )
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}"
}
pwd="$(ask Password)"
echo "Your password is $pwd"
答案 9 :(得分:-1)
#!/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 "-------------------------------"