Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prompt for yes or no in bash?

How do I ask a yes/no type question in Bash?

I ask the question... echo "Do you like pie?"

And receive the answer... read pie

How do I do something if the answer is yes, or starts with y (so yes and yeah, etc, will work too).

like image 750
Ben Aubin Avatar asked Apr 03 '15 16:04

Ben Aubin


People also ask

How do you use yes in bash?

By default, `yes` command repeats the character 'y' if no string value is specified with this command. When `yes` command uses with pipe and another command then it will send the value 'y' or `yes` for any confirmation prompt. This command can help to save time by doing many confirmation tasks automatically.

What does [- Z $1 mean in bash?

$1 means an input argument and -z means non-defined or empty. You're testing whether an input argument to the script was defined when running the script. Follow this answer to receive notifications.


4 Answers

I like to use the following function:

function yes_or_no {
    while true; do
        read -p "$* [y/n]: " yn
        case $yn in
            [Yy]*) return 0  ;;  
            [Nn]*) echo "Aborted" ; return  1 ;;
        esac
    done
}

So in your script you can use like this:

yes_or_no "$message" && do_something

In case the user presses any key other than [yYnN] it will repeat the message.

like image 72
Tiago Lopo Avatar answered Oct 04 '22 23:10

Tiago Lopo


This works too:

read -e -p "Do you like pie? " choice
[[ "$choice" == [Yy]* ]] && echo "doing something" || echo "that was a no"

Pattern starting with Y or y will be taken as yes.

like image 37
Jahid Avatar answered Oct 04 '22 23:10

Jahid


I like Jahid's oneliner. Here is a slight simplification of it:

[[ "$(read -e -p 'Continue? [y/N]> '; echo $REPLY)" == [Yy]* ]]

Here are some tests:

$ [[ "$(read -e -p 'Continue? [y/N]> '; echo $REPLY)" == [Yy]* ]] && echo Continuing || echo Stopping

Continue? [y/N]> yes
Continuing

$ for test_string in y Y yes YES no ''; do echo "Test String: '$test_string'"; echo $test_string | [[ "$(read -e -p 'Continue? [y/N]>'; echo $REPLY)" == [Yy]* ]] && echo Continuing || echo Stopping; done

Test String: 'y'
Continuing

Test String: 'Y'
Continuing

Test String: 'yes'
Continuing

Test String: 'YES'
Continuing

Test String: 'no'
Stopping

Test String: ''
Stopping

Update

In response to a comment, I'm going to add an adaptation to make this work in zsh.

Disclaimer

I would never write a shell script in zsh even though it is now my primary interactive shell. I still write all scripts in bash or sh. However, since you sometimes need to script modifications to your interactive shell (ex: source ~/dev/set_env), you might want to include prompting.

#! /usr/bin/env zsh
[[ "$(echo -n 'Continue? [y/N]> ' >&2; read; echo $REPLY)" == [Yy]* ]] \
  && echo Continuing \
  || echo Stopping
like image 8
Bruno Bronosky Avatar answered Oct 04 '22 23:10

Bruno Bronosky


This works:

echo "Do you like pie?"
read pie
if [[ $pie == y* ]]; then
    echo "You do! Awesome."
else
    echo "I don't like it much, either."
fi

[[ $pie == y* ]] tests to see of the variable $pie starts with y.

Feel free to make this better if you'd like.

like image 6
Ben Aubin Avatar answered Oct 04 '22 23:10

Ben Aubin