Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Hiding User Input in a Shell Script

blog/cards/hiding-user-input-in-a-shell-script.jpg

This could be useful when asking users to input passwords, API tokens or anything you don't want printed to the screen.

Quick Jump: Demo Video

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.

Never Miss a Tip, Trick or Tutorial

Like you, I'm super protective of my inbox, so don't worry about getting spammed. You can expect a few emails per month (at most), and you can 1-click unsubscribe at any time. See what else you'll get too.



Comments