Hiding User Input in a Shell Script
This could be useful when asking users to input passwords, API tokens or anything you don't want printed to the screen.
We’re going to go over 2 solutions. One works with any Bash or Bash-like shell and the other is POSIX compliant if you need maximum compatibility.
The script below includes both solutions. It’s an end to end example that you can run but there’s only 1-3 lines of code near the middle that focus on hiding user input.
You can either comment out option 1 or 2 depending on your use case. Personally
I’d go with option 1 unless you can’t because there are other Bash features
that are useful like being able to set -o pipefail
and other niceties.
#!/usr/bin/env bash
set -o errexit
set -o nounset
while true; do
printf "Please input your API key and hit enter: "
# OPTION 1: REQUIRES A BASH OR BASH-LIKE SHELL (BASH, ZSH, ASH, ETC.)
read -sr key
# OPTION 2: FOR MAXIMUM SHELL COMPATIBILITY (SH, DASH, ETC.)
# stty -echo
# read -r key
# stty echo
if [ -z "${key}" ]; then
printf "\n\nPlease input your API key or hit CTRL+c to halt this script\n\n"
else
# TODO: Insert your custom logic that uses this key.
printf "\n\nFor demo purposes, your API key is: %s\n" "${key}"
break
fi
done
The main difference is the -s
flag from read
isn’t available in sh
and
other minimal shells. The -s
flag prevents echoing user input.
To get around that limitation we can use stty
to disable echoing back our
sensitive text, capturing that input into a variable and then enabling echo
again.
Technically you can omit that last stty echo
and our output will print but
I’ve noticed when using sh
or bash
your prompt will stop echoing input
after this script exits. More modern shells like zsh
seem to auto-correct
this but I don’t know the exact details.
The video below demonstrates all of the above.
# Demo Video
Timestamps
- 0:27 – Quickly going over how it works
- 1:04 – Going over the boiler plate code
- 2:11 – Demonstrating the -s flag for read isn’t POSIX compliant
- 3:07 – A POSIX compliant solution with stty
- 3:54 – A subtle detail with stty and zsh
- 5:57 – Real world use case
What’s your preferred way to hide user input? Let me know below.