Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

bash

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?

like image 758
Tom Avatar asked Dec 11 '09 02:12

Tom


People also ask

How do you prompt a shell script?

The prompt, $, which is called the command prompt, is issued by the shell. While the prompt is displayed, you can type a command. Shell reads your input after you press Enter. It determines the command you want executed by looking at the first word of your input.

How do you ask yes or no in bash?

In that case, we can simply wrap our yes/no prompt in a while loop. #!/bin/bash while true; do read -p "Do you want to proceed? (yes/no) " yn case $yn in yes ) echo ok, we will proceed; break;; no ) echo exiting...; exit;; * ) echo invalid response;; esac done echo doing stuff...

How do I customize the prompt in bash?

Bash has four prompt strings that can be customized: PS0 is displayed after each command, before any output. PS1 is the primary prompt which is displayed before each command, thus it is the one most people customize. PS2 is the secondary prompt displayed when a command needs more input (e.g. a multi-line command).


2 Answers

read -p "Are you sure? " -n 1 -r echo    # (optional) move to a new line if [[ $REPLY =~ ^[Yy]$ ]] then     # do dangerous stuff fi 

I incorporated levislevis85's suggestion (thanks!) and added the -n option to read to accept one character without the need to press Enter. You can use one or both of these.

Also, the negated form might look like this:

read -p "Are you sure? " -n 1 -r echo    # (optional) move to a new line if [[ ! $REPLY =~ ^[Yy]$ ]] then     [[ "$0" = "$BASH_SOURCE" ]] && exit 1 || return 1 # handle exits from shell or function but don't exit interactive shell fi 

However, as pointed out by Erich, under some circumstances such as a syntax error caused by the script being run in the wrong shell, the negated form could allow the script to continue to the "dangerous stuff". The failure mode should favor the safest outcome so only the first, non-negated if should be used.

Explanation:

The read command outputs the prompt (-p "prompt") then accepts one character (-n 1) and accepts backslashes literally (-r) (otherwise read would see the backslash as an escape and wait for a second character). The default variable for read to store the result in is $REPLY if you don't supply a name like this: read -p "my prompt" -n 1 -r my_var

The if statement uses a regular expression to check if the character in $REPLY matches (=~) an upper or lower case "Y". The regular expression used here says "a string starting (^) and consisting solely of one of a list of characters in a bracket expression ([Yy]) and ending ($)". The anchors (^ and $) prevent matching longer strings. In this case they help reinforce the one-character limit set in the read command.

The negated form uses the logical "not" operator (!) to match (=~) any character that is not "Y" or "y". An alternative way to express this is less readable and doesn't as clearly express the intent in my opinion in this instance. However, this is what it would look like: if [[ $REPLY =~ ^[^Yy]$ ]]

like image 138
Dennis Williamson Avatar answered Sep 20 '22 20:09

Dennis Williamson


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.
like image 42
ghostdog74 Avatar answered Sep 20 '22 20:09

ghostdog74