# 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"
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