2

The question was to write a script that checks whether the character read is "Y", "y","n" or "N", and display the result accordingly.

However, I'm getting the output YES for every input I give. I'm a complete novice in scripting and can't figure out what might be causing this.

Here's the code:

#!/bin/bash
read CHAR

if [ [$CHAR=="Y"] -o [$CHAR=="y"] ]; then
        echo "YES"
elif [ [$CHAR=="N"] -o [$CHAR=="n"] ]; then
        echo "NO"
fi
r0hit
  • 21
  • 2

4 Answers4

3

Brackets do not work like parenthesis in test expressions. Also, test uses =, not ==. And you also need to split to expressions properly into tokens (by adding spaces around the = signs). So what you want, rather, is this:

if [ "$CHAR" = Y -o "$CHAR" = y ]; then
    echo "YES"
elif [ "$CHAR" = N -o "$CHAR" = n ]; then
    echo "NO"
fi

Notice that I've also quoted "$CHAR". This makes the program more robust in the cases where $CHAR is empty or contains spaces. The Y and N, on the other hand, do not need any quoting as they are constants and contain no whitespace.

To be more precise, what happens in your program as that each of the $CHAR expressions expand to a single token that looks something like [N==Y], which is a token without special significance for test. Any token that lacks special significance is interpreted by test as a "true".

Dolda2000
  • 25,216
  • 4
  • 51
  • 92
1

You need to use single = for string comparison and you've too many brackets. So the code becomes:

#!/bin/bash
read CHAR

if [ "$CHAR" = "Y" -o "$CHAR" = "y" ]; then
  echo "YES"
elif [ "$CHAR" = "N" -o "$CHAR"="n" ]; then
  echo "NO"
fi

Next time when you'd like to debug your script why it doesn't work, run is as: bash -x ./script.sh or add -x in your first line after bash.


Check the following one-liner:

read CHAR && [ "${CHAR^^}" = "Y" ] && echo YES || echo NO

It's using bash parameter expansion, see: Case Insensitive comparision of strings in Shell script.

Community
  • 1
  • 1
kenorb
  • 155,785
  • 88
  • 678
  • 743
  • Thanks!! It worked. But can you explain the significance of correct spacing in scripting? I haven't figured it out yet. – r0hit Mar 04 '15 at 13:56
  • @ZeWisdom It's just cleaner and easier to read and more towards common coding standards, so it's a good practice. Secondly sometimes bash fails when you don't put a space between expressions, like right next to the brackets (`[`, `]`). – kenorb Mar 04 '15 at 14:00
  • 2
    That's because `[` isn't a shell syntax thing. It is a command (see `ls /usr/bin[` for example) and so it needs to be its own word to work correctly. You wouldn't expect `echo"$CHAR"` to work would you? – Etan Reisner Mar 04 '15 at 14:20
1

a case statement can be quite readable

read char
case ${char,} in
  y*) echo Yes;;
  n*) echo No;;
esac

https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
0
#!/bin/bash
read "CHAR"

if [[ "$CHAR" == "Y" || "$CHAR" == "y" ]]; then
        echo "YES"
elif [[ "$CHAR" == "N" || "$CHAR" == "n" ]]; then
        echo "NO"
fi

Try this out! The problem seems to be the usage of "-o" with double "=", and the spaces in if and elif for the parenthesis.