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 '11 at 15:50
  • A programming answer might be something like Bash: Check if array element exists – phunehehe May 22 '11 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. – Gilles 'SO- stop being evil' May 22 '11 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*" – Ben Jackson May 22 '11 at 21:38

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’. – Aeyoun May 22 '11 at 18:29

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. – dmckee --- ex-moderator kitten May 22 '11 at 20:48
  • Nice. Could you please link back to the source? – Aeyoun May 22 '11 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 '11 at 22:20
  • 1
    Great answer, should definitely be the accepted one. – jlliagre Sep 16 '13 at 11:52

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 '16 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.