How can one read passwords in bash scripts in such a way that tools do not show it on a terminal?
(Changing font to black-on-black is easily worked around by copy & paste, so it's not solution.)
From help read
:
-s do not echo input coming from a terminal
For example, to prompt the user and read an arbitrary password into the variable passwd
,
IFS= read -s -p 'Password please: ' passwd
man read
, I haven't check in help read
. Good to know.
Commented
Mar 26, 2012 at 21:19
man bash
and there you can find -s option Silent mode. If input is coming from a terminal, characters are not echoed.
Commented
Mar 27, 2012 at 6:34
I always used stty -echo
to turn echoing off, then read and afterwards do stty echo
(read more by viewing man of stty
- i.e. man stty
). This is more useful from a programmers perspective as you can turn echoing off and then read a password from a programming language such as Java, C(++), Python, etc. with their standard stdin "readers."
In bash, the usage could look like this:
echo -n "USERNAME: "; IFS= read -r uname
echo -n "PASSWORD: "; stty -echo; IFS= read -r passwd; stty echo; echo
program "$uname" "$passwd"
unset -v passwd # get rid of passwd
Python, for example, would look like:
from sys import stdout
from os import system as term
uname = raw_input("USERNAME: ") # read input from stdin until [Enter] in 2
stdout.write("PASSWORD: ")
term("stty -echo") # turn echo off
try:
passwd = raw_input()
except KeyboardInterrupt: # ctrl+c pressed
raise SystemExit("Password attempt interrupted")
except EOFError: # ctrl+d pressed
raise SystemExit("Password attempt interrupted")
finally:
term("stty echo") # turn echo on again
print "username:", uname
print "password:", "*" * len(passwd)
I had to do this a lot of times in Python, so I know it pretty well from that perspective. This isn't very hard to translate to other languages, though.
stty -echo; sleep 3; stty echo
makes any characters entered show up after the last command has completed.
If you're fine with adding an external dependency, you may use a password box provided by tools such as dialog or whiptail.
If running in an Apple-flavored zsh
shell, builtins like read
accept different args (BSD-flavored?), namely they interpret -p
as another process to read from and you'll get the error
read: -p: no coprocess
In that case, you can make the prompt separately:
printf "Password please: "
IFS= read -s PASSWD
Where the password will be held in the envvar PASSWD
.
Your question reads kind of different "in a way like tools???" so I don't exactly know if this will work for you:
system1 $ passwd=abc123
system1 $ printf "%s\n" "${passwd//?/*}"
******
termios
,stty
,read -s
, anything that does it.