Usability testing of a shell script I wrote found that people had different expectations on how to answer a question that expected ‘yes’ as the answer. See variations in the below code example.

Surely there must be a better way that what I came up with? What is your readable and shorter form take on this?

read -p 'Answer this question with yes: ' answer
if [ "$answer" = 'Y'
  -o "$answer" = 'YES'
  -o "$answer" = 'Yes'
  -o "$answer" = 'y'
  -o "$answer" = 'yes'
  -o some-alternate-condition ]; then

  echo 'Surely this can be written better?'
  • 2
    Voted to close. While I'm interested in the question, it's probably more of a programming question, so should be on SO.
    – phunehehe
    May 22, 2011 at 15:50
  • A programming answer might be something like Bash: Check if array element exists
    – phunehehe
    May 22, 2011 at 15:57
  • 3
    @phunehehe: I disagree with moving to SO, not only because we have a history of accepting shell programming, but also because it's not just a question of how to do it but also a question of what the spec should be. May 22, 2011 at 16:00
  • 4
    I wrote a script much like that once. Then the program was translated to French and Simplified Chinese. I skimmed the French version and saw my prompt was translated to "Enter oui or non" but of course the code still wanted "Y*" or "N*" May 22, 2011 at 21:38

5 Answers 5


The UNIX standard provides example code for this using the locale utility:

if printf "%s\n" "$response" | grep -Eq "$(locale yesexpr)"
    affirmative processing goes here
    non-affirmative processing goes here

The value for 'yesexpr' in the POSIX locale (and on English locales on real systems) is "^[yY]". It is to be interpreted as an extended regular expression. See also noexpr.

  • 1
    Nice. But I seem to be an idiot. Where can I find a list of the arguments that locale knows about? The man page on my Mac OS 10.5 box doesn't seem to have them. May 22, 2011 at 20:48
  • Nice. Could you please link back to the source?
    – Daniel
    May 22, 2011 at 21:51
  • 3
    @dmckee you can do locale -k LC_MESSAGES (and for the other LC_whatever), or see here for ones defined by the standard. @Daniel what source other than the locale utility page that I did link?
    – Random832
    May 22, 2011 at 22:20
  • 1
    Great answer, should definitely be the accepted one.
    – jlliagre
    Sep 16, 2013 at 11:52

Using a case is somewhat equivalent but not perfect since statements like YE are accepted.

read -p 'Answer this question with yes: ' answer
case "${answer}" in
        echo 'Surely this can be written better?' ;;
  • 3
    I would say the user’s intent is pretty clear from ‘ye’.
    – Daniel
    May 22, 2011 at 18:29

Staying in bash (or any other shell if you display the prompt independently):

case $answer in
  [Yy]*) echo Ok;;
  *) echo "Can't you read? I said to say yes.";;

This accepts responses like yn as yes,  y (with an initial space) as no, and wlkjzuhfod as no, which may not be optimal but is consistent with typical shell prompts: that's how rm -i, find -ok and others do it.

This eschews the whole issue of internationalization: in other languages, you would need to translate expected responses. There's no standard shell method then; you can turn to dialog, but then your script will require it to be installed (it's available in many distributions but not always installed by default).

if dialog --yesno "Choose yes" 0 0; then …

I usually use a simple function:

Confirm() { read -sn 1 -p "$* [Y/N]? "; [[ ${REPLY:0:1} = [Yy] ]]; }

The function just returns 0 if Y or y is entered and 1 if anything else is entered. It can be used with if...fi:

if Confirm "Type y or n"; then
echo "You typed y"
echo "You typed n"

Or just like this:

Confirm "Type y" && echo "You typed y"
  • Take off the -s to have a visual history of what what was typed.
    – Tom Hale
    Sep 11, 2016 at 10:47

Just re-modified @faif ans

YesOrNo() {
        while :
                read -p 'Do you want to Continue (yes/no?): ' answer
                case "${answer}" in
                    [yY]|[yY][eE][sS]) exit 0 ;;
                        [nN]|[nN][oO]) exit 1 ;;

if $( YesOrNo ); then
        echo "Ans is yes.. Do something....."
        echo "Ans is No... skip.."


root@ubuntu:~# bash confirm.sh
Do you want to Continue (yes/no?):  # if Blank Enter then ask again
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?): no
Ans is No... skip..
root@ubuntu:~# bash confirm.sh
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?):
Do you want to Continue (yes/no?): ye
Do you want to Continue (yes/no?): yes
Ans is yes.. Do something.....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.