[bash] How do I prompt a user for confirmation in bash script?

I want to put a quick "are you sure?" prompt for confirmation at the top of a potentially dangerous bash script, what's the easiest/best way to do this?

This question is related to bash

The answer is


Try the read shell builtin:

read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
  echo "yaaa";
else
  echo "booo";
fi

use case/esac.

read -p "Continue (y/n)?" choice
case "$choice" in 
  y|Y ) echo "yes";;
  n|N ) echo "no";;
  * ) echo "invalid";;
esac

advantage:

  1. neater
  2. can use "OR" condition easier
  3. can use character range, eg [yY][eE][sS] to accept word "yes", where any of its characters may be in lowercase or in uppercase.

[[ -f ./${sname} ]] && read -p "File exists. Are you sure? " -n 1

[[ ! $REPLY =~ ^[Yy]$ ]] && exit 1

used this in a function to look for an existing file and prompt before overwriting.


#!/bin/bash
echo Please, enter your name
read NAME
echo "Hi $NAME!"
if [ "x$NAME" = "xyes" ] ; then
 # do something
fi

I s a short script to read in bash and echo back results.


Here's the function I use :

function ask_yes_or_no() {
    read -p "$1 ([y]es or [N]o): "
    case $(echo $REPLY | tr '[A-Z]' '[a-z]') in
        y|yes) echo "yes" ;;
        *)     echo "no" ;;
    esac
}

And an example using it:

if [[ "no" == $(ask_yes_or_no "Are you sure?") || \
      "no" == $(ask_yes_or_no "Are you *really* sure?") ]]
then
    echo "Skipped."
    exit 0
fi

# Do something really dangerous...
  • The output is always "yes" or "no"
  • It's "no" by default
  • Everything except "y" or "yes" returns "no", so it's pretty safe for a dangerous bash script
  • And it's case insensitive, "Y", "Yes", or "YES" work as "yes".

I hope you like it,
Cheers!


qnd: use

read VARNAME
echo $VARNAME

for a one line response without readline support. Then test $VARNAME however you want.


echo are you sure?
read x
if [ "$x" = "yes" ]
then
  # do the dangerous stuff
fi

This what I found elsewhere, is there a better possible version?

read -p "Are you sure you wish to continue?"
if [ "$REPLY" != "yes" ]; then
   exit
fi

This way you get 'y' 'yes' or 'Enter'

 read -r -p "Are you sure? [Y/n]" response
 response=${response,,} # tolower
 if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
    your-action-here
 fi

If you are using zsh try this:

read "response?Are you sure ? [Y/n] "
response=${response:l} #tolower
if [[ $response =~ ^(yes|y| ) ]] || [[ -z $response ]]; then
    your-action-here
fi