I have bash script like the following:
我有如下的bash脚本:
#!/bin/bash
echo "Please enter your username";
read username;
echo "Please enter your password";
read password;
I want that when the user types the password on the terminal, it should not be displayed (or something like *******) should be displayed). How do I achieve this?
我希望当用户在终端上输入密码时,不应该显示密码(或者应该显示类似于******* ****的内容)。我该如何做到这一点?
8 个解决方案
#1
203
Just supply -s to your read call like so:
只要像这样为你的阅读电话提供-s:
$ read -s PASSWORD
$ echo $PASSWORD
#2
21
Update
In case you want to get fancy by outputting an *
for each character they type, you can do something like this (using andreas' read -s
solution):
如果你想为他们输入的每个字符输出一个*,你可以这样做(使用andreas的read -s解决方案):
unset password;
while IFS= read -r -s -n1 pass; do
if [[ -z $pass ]]; then
echo
break
else
echo -n '*'
password+=$pass
fi
done
Without being fancy
没有花哨的
echo "Please enter your username";
read username;
echo "Please enter your password";
stty -echo
read password;
stty echo
#3
11
for a solution that works without bash or certain features from read
you can use stty
to disable echo
对于不使用bash或read中的某些特性的解决方案,可以使用stty禁用echo
stty_orig=`stty -g`
stty -echo
read password
stty $stty_orig
#4
6
Here's a variation on @SiegeX's excellent *
-printing solution for bash
with support for backspace added; this allows the user to correct their entry with the backspace
key (delete
key on a Mac), as is typically supported by password prompts:
下面是@SiegeX关于bash的优秀*打印解决方案的一个变体,它支持添加回退空间;这允许用户使用backspace密钥(Mac上的删除密钥)来更正他们的条目,密码提示通常支持这一点:
#!/usr/bin/env bash
password=''
while IFS= read -r -s -n1 char; do
[[ -z $char ]] && { printf '\n'; break; } # ENTER pressed; output \n and break.
if [[ $char == $'\x7f' ]]; then # backspace was pressed
# Remove last char from output variable.
[[ -n $password ]] && password=${password%?}
# Erase '*' to the left.
printf '\b \b'
else
# Add typed char to output variable.
password+=$char
# Print '*' in its stead.
printf '*'
fi
done
Note:
注意:
- As for why pressing backspace records character code
0x7f
: "In modern systems, the backspace key is often mapped to the delete character (0x7f in ASCII or Unicode)" https://en.wikipedia.org/wiki/Backspace - 至于为什么按下backspace记录字符代码0x7f:“在现代系统中,backspace键通常映射到delete字符(ASCII或Unicode中的0x7f)”https://en.wikipedia.org/wiki/Backspace
-
\b \b
is needed to give the appearance of deleting the character to the left; just using\b
moves the cursor to the left, but leaves the character intact (nondestructive backspace). By printing a space and moving back again, the character appears to have been erased (thanks, The "backspace" escape character '\b' in C, unexpected behavior?). - \b \b需要提供删除左边字符的外观;只需使用\b将光标移到左边,但保留字符不变(非破坏性回格)。通过打印一个空格并再次移动,这个字符看起来已经被删除(谢谢,C中的“backspace”转义字符“\b”,意外行为?)
In a POSIX-only shell (e.g., sh
on Debian and Ubuntu, where sh
is dash
), use the stty -echo
approach (which is suboptimal, because it prints nothing), because the read
builtin will not support the -s
and -n
options.
在纯posix shell(例如,Debian和Ubuntu上的sh,其中sh是dash)中,使用stty -echo方法(这是次优方法,因为它不打印任何内容),因为read builtin不支持-s和-n选项。
#5
2
Here is a variation of @SiegeX's answer which works with traditional Bourne shell (which has no support for +=
assignments).
下面是@SiegeX的一个变体,它与传统的Bourne shell兼容(不支持+= assignments)。
password=''
while IFS= read -r -s -n1 pass; do
if [ -z "$pass" ]; then
echo
break
else
printf '*'
password="$password$pass"
fi
done
#6
2
I always like to use Ansi escape characters:
我总是喜欢用Ansi转义字符:
echo -e "Enter your password: \x1B[8m"
echo -e "\x1B[0m"
8m
makes text invisible and 0m
resets text to "normal." The -e makes Ansi escapes possible.
8m将文本重置为“normal”。e使Ansi逃脱成为可能。
The only caveat is that you can still copy and paste the text that is there, so you probably shouldn't use this if you really want security.
唯一要注意的是,您仍然可以复制和粘贴那里的文本,因此如果您真的想要安全性,您可能不应该使用这个。
It just lets people not look at your passwords when you type them in. Just don't leave your computer on afterwards. :)
它只是让人们在你输入密码时不用看你的密码。不要把你的电脑一直开着。:)
NOTE:
注意:
The above is platform independent as long as it supports Ansi escape sequences.
只要支持Ansi转义序列,以上是独立于平台的。
However, for another Unix solution, you could simply tell read
to not echo the characters...
但是,对于另一个Unix解决方案,您可以简单地告诉read不要回显字符……
printf "password: "
let pass $(read -s)
printf "\nhey everyone, the password the user just entered is $pass\n"
#7
2
A bit different from (but mostly like) @lesmana's answer
这和@lesmana的回答有点不同(但主要是类似的)
stty -echo
read password
stty echo
simply: hide echo do your stuff show echo
简单来说:隐藏echo做你的东西显示echo
#8
0
Get Username and password
获得用户名和密码
Make it more clear to read but put it on a better position over the screen
让它读起来更清晰,但是把它放在屏幕上更好的位置
#!/bin/bash
clear
echo
echo
echo
counter=0
unset username
prompt=" Enter Username:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
if [[ $char == $'\0' ]]; then
break
elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
prompt=$'\b \b'
username="${username%?}"
counter=$((counter-1))
elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
prompt=''
continue
else
counter=$((counter+1))
prompt="$char"
username+="$char"
fi
done
echo
unset password
prompt=" Enter Password:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
if [[ $char == $'\0' ]]; then
break
elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
prompt=$'\b \b'
password="${password%?}"
counter=$((counter-1))
elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
echo
prompt=" Enter Password:"
continue
else
counter=$((counter+1))
prompt='*'
password+="$char"
fi
done
#1
203
Just supply -s to your read call like so:
只要像这样为你的阅读电话提供-s:
$ read -s PASSWORD
$ echo $PASSWORD
#2
21
Update
In case you want to get fancy by outputting an *
for each character they type, you can do something like this (using andreas' read -s
solution):
如果你想为他们输入的每个字符输出一个*,你可以这样做(使用andreas的read -s解决方案):
unset password;
while IFS= read -r -s -n1 pass; do
if [[ -z $pass ]]; then
echo
break
else
echo -n '*'
password+=$pass
fi
done
Without being fancy
没有花哨的
echo "Please enter your username";
read username;
echo "Please enter your password";
stty -echo
read password;
stty echo
#3
11
for a solution that works without bash or certain features from read
you can use stty
to disable echo
对于不使用bash或read中的某些特性的解决方案,可以使用stty禁用echo
stty_orig=`stty -g`
stty -echo
read password
stty $stty_orig
#4
6
Here's a variation on @SiegeX's excellent *
-printing solution for bash
with support for backspace added; this allows the user to correct their entry with the backspace
key (delete
key on a Mac), as is typically supported by password prompts:
下面是@SiegeX关于bash的优秀*打印解决方案的一个变体,它支持添加回退空间;这允许用户使用backspace密钥(Mac上的删除密钥)来更正他们的条目,密码提示通常支持这一点:
#!/usr/bin/env bash
password=''
while IFS= read -r -s -n1 char; do
[[ -z $char ]] && { printf '\n'; break; } # ENTER pressed; output \n and break.
if [[ $char == $'\x7f' ]]; then # backspace was pressed
# Remove last char from output variable.
[[ -n $password ]] && password=${password%?}
# Erase '*' to the left.
printf '\b \b'
else
# Add typed char to output variable.
password+=$char
# Print '*' in its stead.
printf '*'
fi
done
Note:
注意:
- As for why pressing backspace records character code
0x7f
: "In modern systems, the backspace key is often mapped to the delete character (0x7f in ASCII or Unicode)" https://en.wikipedia.org/wiki/Backspace - 至于为什么按下backspace记录字符代码0x7f:“在现代系统中,backspace键通常映射到delete字符(ASCII或Unicode中的0x7f)”https://en.wikipedia.org/wiki/Backspace
-
\b \b
is needed to give the appearance of deleting the character to the left; just using\b
moves the cursor to the left, but leaves the character intact (nondestructive backspace). By printing a space and moving back again, the character appears to have been erased (thanks, The "backspace" escape character '\b' in C, unexpected behavior?). - \b \b需要提供删除左边字符的外观;只需使用\b将光标移到左边,但保留字符不变(非破坏性回格)。通过打印一个空格并再次移动,这个字符看起来已经被删除(谢谢,C中的“backspace”转义字符“\b”,意外行为?)
In a POSIX-only shell (e.g., sh
on Debian and Ubuntu, where sh
is dash
), use the stty -echo
approach (which is suboptimal, because it prints nothing), because the read
builtin will not support the -s
and -n
options.
在纯posix shell(例如,Debian和Ubuntu上的sh,其中sh是dash)中,使用stty -echo方法(这是次优方法,因为它不打印任何内容),因为read builtin不支持-s和-n选项。
#5
2
Here is a variation of @SiegeX's answer which works with traditional Bourne shell (which has no support for +=
assignments).
下面是@SiegeX的一个变体,它与传统的Bourne shell兼容(不支持+= assignments)。
password=''
while IFS= read -r -s -n1 pass; do
if [ -z "$pass" ]; then
echo
break
else
printf '*'
password="$password$pass"
fi
done
#6
2
I always like to use Ansi escape characters:
我总是喜欢用Ansi转义字符:
echo -e "Enter your password: \x1B[8m"
echo -e "\x1B[0m"
8m
makes text invisible and 0m
resets text to "normal." The -e makes Ansi escapes possible.
8m将文本重置为“normal”。e使Ansi逃脱成为可能。
The only caveat is that you can still copy and paste the text that is there, so you probably shouldn't use this if you really want security.
唯一要注意的是,您仍然可以复制和粘贴那里的文本,因此如果您真的想要安全性,您可能不应该使用这个。
It just lets people not look at your passwords when you type them in. Just don't leave your computer on afterwards. :)
它只是让人们在你输入密码时不用看你的密码。不要把你的电脑一直开着。:)
NOTE:
注意:
The above is platform independent as long as it supports Ansi escape sequences.
只要支持Ansi转义序列,以上是独立于平台的。
However, for another Unix solution, you could simply tell read
to not echo the characters...
但是,对于另一个Unix解决方案,您可以简单地告诉read不要回显字符……
printf "password: "
let pass $(read -s)
printf "\nhey everyone, the password the user just entered is $pass\n"
#7
2
A bit different from (but mostly like) @lesmana's answer
这和@lesmana的回答有点不同(但主要是类似的)
stty -echo
read password
stty echo
simply: hide echo do your stuff show echo
简单来说:隐藏echo做你的东西显示echo
#8
0
Get Username and password
获得用户名和密码
Make it more clear to read but put it on a better position over the screen
让它读起来更清晰,但是把它放在屏幕上更好的位置
#!/bin/bash
clear
echo
echo
echo
counter=0
unset username
prompt=" Enter Username:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
if [[ $char == $'\0' ]]; then
break
elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
prompt=$'\b \b'
username="${username%?}"
counter=$((counter-1))
elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
prompt=''
continue
else
counter=$((counter+1))
prompt="$char"
username+="$char"
fi
done
echo
unset password
prompt=" Enter Password:"
while IFS= read -p "$prompt" -r -s -n 1 char
do
if [[ $char == $'\0' ]]; then
break
elif [ $char == $'\x08' ] && [ $counter -gt 0 ]; then
prompt=$'\b \b'
password="${password%?}"
counter=$((counter-1))
elif [ $char == $'\x08' ] && [ $counter -lt 1 ]; then
echo
prompt=" Enter Password:"
continue
else
counter=$((counter+1))
prompt='*'
password+="$char"
fi
done