0

I'm having an issue getting a a simple y/n question to work. Consider the following code:

 echo "Hi there"
 read ans
 if [[ $ans != "y" || $ans != "Y" || $ans != "YES" || $ans != "yes" ]]; then
      echo "Foo"
      exit 0
 fi

I've looked at – I would argue – some of the more informative answers on StackOverflow for advice: Simple logical operators in Bash

I've tried all different types of variations such as:

if [[ ($ans != "y" || $ans != "Y" || $ans != "YES" || $ans != "yes") ]]; then
    echo "Foo"
    exit 0
fi

if [[ ($ans != "y*" || $ans != "Y*" || $ans != "YES*" || $ans != "yes*") ]]; then
    echo "Foo"
    exit 0
fi

if [[ ($ans != "y") || ($ans != "Y") || ($ans != "YES") || ($ans != "yes") ]]; then
    echo "Foo"
    exit 0
fi

Regardless of why I type in any of these cases, it automatically fails and I'm not sure why. If anyone has a better way to handle y/n answers then please let me know! Ideally I would like to use pattern matching (like I might do with Perl) but I'm not entirely sure the best way/most efficient way to accomplish a simple y/n question.

Community
  • 1
  • 1
djthoms
  • 3,026
  • 2
  • 31
  • 56

4 Answers4

3

You need to use && instead of ||. As it stands you're saying if it's not equal to any of those possibilities, then execute the "then" block. You mean to say if it's not equal to all of them, then execute the "then" block. That requires &&.

ooga
  • 15,423
  • 2
  • 20
  • 21
  • Face palm... It must be something between too late or too early. I'll make this as the answer when SO allows me to – djthoms May 26 '14 at 19:20
3

You can use:

echo "Hi there"
read ans
case "$ans" in
    y|Y|YES|yes)
        ;;

    *)
      echo "Foo"
      exit 0
      ;;
esac
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
2

The logic needs to be adjusted:

echo "Hi there"
read ans
if ! [[ "$ans" == "y" || "$ans" == "Y" || "$ans" == "YES" || "$ans" == "yes" ]]; then
     echo "Foo"  # User answered no
     exit 0
fi

The will echo "Foo" only if the answer was not one of "y", "Y" or "YES". By contrast, consider the original logic:

[[ $ans != "y" || $ans != "Y" || $ans != "YES" || $ans != "yes" ]]

At least one of these tests will be true regardless of what the user's answer is.

Using the case statement

You might consider using the case statement to analyze the user's answer:

read -p "Hi there: " ans
case "$ans" in
    [yY]*) ;;
    [nN]*) echo "Foo" ; exit 0 ;;
    *) echo "You were supposed to answer yes or no" ;;
esac
John1024
  • 109,961
  • 14
  • 137
  • 171
0

Try read ans, not read $ans.

Vytenis Bivainis
  • 2,308
  • 21
  • 28