17

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 option don't exists :

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

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

20

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.

#!/bin/bash
stty -echo
printf "Password: "
read PASSWORD
stty echo
printf "\n"

This will work on all shells that conform to POSIX.

Source

  • 2
    Dear downvoter please do not forget to leave a comment. – serenesat Aug 13 '15 at 11:58
  • 6
    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 '15 at 12:36
  • read the linked answer or see Stephane's answer in this thread – Jeff Schaller Aug 13 '15 at 15:00
  • 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 '15 at 19:37
23
read_password() {
  REPLY="$(
    # 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 (mksh) where printf is not builtin, the password will 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.

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.