When I want to ask for a password in a bash script, I do that :

read -s

...but when I run bash in POSIX mode, with sh, the -s option is rejected:

$ read -s
sh: 1: read: Illegal option -s

How do I securely ask for an input with a POSIX-compliant command ?


2 Answers 2

read_password() {
    # always read from the tty even when redirected:
    exec < /dev/tty || exit # || exit only needed for bash

    # save current tty settings:
    tty_settings=$(stty -g) || exit

    # schedule restore of the settings on exit of that subshell
    # or on receiving SIGINT or SIGTERM:
    trap 'stty "$tty_settings"' EXIT INT TERM

    # disable terminal local echo
    stty -echo || exit

    # prompt on tty
    printf "Password: " > /dev/tty

    # read password as one line, record exit status
    IFS= read -r password; ret=$?

    # display a newline to visually acknowledge the entered password
    echo > /dev/tty

    # return the password for $REPLY
    printf '%s\n' "$password"
    exit "$ret"

Note that for those shells (ksh88, mksh and most other pdksh-derived shells) where printf is not builtin, the password would appear in clear in the ps output (for a few microseconds) or may show up in some audit logs if all command invocations with their parameters are audited. In those shells however, you can replace it with print -r -- "$password".

In any case echo is generally not an option.

Another POSIX-compliant one that doesn't involve revealing the password in the ps output (but might end up having it written onto permanent storage) is:

cat << EOF

Also note that zsh's IFS= read -rs 'pass?Password: ' or bash's IFS= read -rsp 'Password: ' pass issue the Password: prompt on stderr. So with those, you might want to add a 2> /dev/tty to make sure the prompt goes to the controlling terminal.

In any case, make sure you don't forget the IFS= and -r.


read -s is not in POSIX. If you want to be POSIX-compliant use the stty -echo. stty and its echo parameter are defined in POSIX.

stty -echo
printf "Password: "
stty echo
printf "\n"

This will work on all shells that conform to POSIX.


  • 8
    to highlight a point from the answer in @arkadiusz-drabczyk's comment, it'd be a good idea to trap all the signals you can in order to turn stty echo back on -- in case the user gets confused and hits control-C during the read PASSWORD section.
    – Jeff Schaller
    Aug 13, 2015 at 12:36
  • read the linked answer or see Stephane's answer in this thread
    – Jeff Schaller
    Aug 13, 2015 at 15:00
  • 2
    You shouldn't turn on echoing unconditionally, you should save and restore the old setting. Many people work in Emacs shell buffers, and this normally has echoing disabled because Emacs is doing the echoing itself. The other answer shows how to do this.
    – Barmar
    Aug 19, 2015 at 19:37

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .