How to get a password from a shell script without echoing
Solution 1
Here is another way to do it:
#!/bin/bash
# Read Password
echo -n Password:
read -s password
echo
# Run Command
echo $password
The read -s
will turn off echo for you. Just replace the echo
on the last line with the command you want to run.
Solution 2
A POSIX compliant answer. Notice the use of /bin/sh
instead of /bin/bash
. (It does work with bash, but it does not require bash.)
#!/bin/sh
stty -echo
printf "Password: "
read PASSWORD
stty echo
printf "\n"
Solution 3
One liner:
read -s -p "Password: " password
Under Linux (and cygwin) this form works in bash and sh. It may not be standard Unix sh, though.
For more info and options, in bash, type "help read".
$ help read
read: read [-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]
Read a line from the standard input and split it into fields.
...
-p prompt output the string PROMPT without a trailing newline before
attempting to read
...
-s do not echo input coming from a terminal
Solution 4
The -s
option of read
is not defined in the POSIX standard. See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/read.html. I wanted something that would work for any POSIX shell, so I wrote a little function that uses stty
to disable echo.
#!/bin/sh
# Read secret string
read_secret()
{
# Disable echo.
stty -echo
# Set up trap to ensure echo is enabled before exiting if the script
# is terminated while echo is disabled.
trap 'stty echo' EXIT
# Read secret.
read "$@"
# Enable echo.
stty echo
trap - EXIT
# Print a newline because the newline entered by the user after
# entering the passcode is not echoed. This ensures that the
# next line of output begins at a new line.
echo
}
This function behaves quite similar to the read
command. Here is a simple usage of read
followed by similar usage of read_secret
. The input to read_secret
appears empty because it was not echoed to the terminal.
[susam@cube ~]$ read a b c
foo \bar baz \qux
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=bar c=baz qux
[susam@cube ~]$ unset a b c
[susam@cube ~]$ read_secret a b c
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=bar c=baz qux
[susam@cube ~]$ unset a b c
Here is another that uses the -r
option to preserve the backslashes in the input. This works because the read_secret
function defined above passes all arguments it receives to the read
command.
[susam@cube ~]$ read -r a b c
foo \bar baz \qux
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=\bar c=baz \qux
[susam@cube ~]$ unset a b c
[susam@cube ~]$ read_secret -r a b c
[susam@cube ~]$ echo a=$a b=$b c=$c
a=foo b=\bar c=baz \qux
[susam@cube ~]$ unset a b c
Finally, here is an example that shows how to use the read_secret
function to read a password in a POSIX compliant manner.
printf "Password: "
read_secret password
# Do something with $password here ...
Solution 5
I found to be the the askpass
command useful
password=$(/lib/cryptsetup/askpass "Give a password")
Every input character is replaced by *. See: Give a password ****
BD at Rivenhill
I'm working on the following projects (not necessarily in order): Software for automated trading (focusing on both high throughput and low latency) Robots
Updated on March 17, 2021Comments
-
BD at Rivenhill about 3 years
I have a script that automates a process that needs access to a password protected system. The system is accessed via a command-line program that accepts the user password as an argument.
I would like to prompt the user to type in their password, assign it to a shell variable, and then use that variable to construct the command line of the accessing program (which will of course produce stream output that I will process).
I am a reasonably competent shell programmer in Bourne/Bash, but I don't know how to accept the user input without having it echo to the terminal (or maybe having it echoed using '*' characters).
Can anyone help with this?