39

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.)

Kev
  • 1,739
  • 4
  • 27
  • 48
  • 6
    For anyone reading this: do NOT read in passwords with echo on and black-on-black. The password is still transmitted, and if the terminal doesn't know the terminal directives you've used, characters will echo visibly. Turn echo off. Use termios, stty, read -s, anything that does it. – Alexios Mar 26 '12 at 22:14
  • 1
    That's why I've wrote, that it is not a solution ;). – Grzegorz Wierzowiecki Mar 26 '12 at 22:18
  • 1
    Indeed! Sometimes people skim questions and come to misguided conclusions. :) – Alexios Mar 26 '12 at 22:25

4 Answers4

50

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
Kusalananda
  • 333,661
  • 2
    Great. It's not written in my man read, I haven't check in help read. Good to know. – Grzegorz Wierzowiecki Mar 26 '12 at 21:19
  • 5
    @GrzegorzWierzowiecki: You are viewing the wrong manual. you have to read the manual of bash i.e man bash and there you can find -s option Silent mode. If input is coming from a terminal, characters are not echoed. – pradeepchhetri Mar 27 '12 at 06:34
11

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.

Kusalananda
  • 333,661
Dylan
  • 435
  • I'm finding that stty -echo; sleep 3; stty echo makes any characters entered show up after the last command has completed. – hennes Jul 08 '22 at 19:07
0

If you're fine with adding an external dependency, you may use a password box provided by tools such as dialog or whiptail.

Whiptail

Peregrino69
  • 2,417
Deyan
  • 1
-2

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//?/*}"
******
2bc
  • 3,978