2

The test seems not to work properly. Why ? I need a script which takes the first argument, checks which letter it is and does the job. If the letter is a,b,c or d it exits, otherwise rights something.

letter=$1                                                                                                                                             


[[ $letter != a || $letter != b || $letter != c || $letter != d ]] && echo exiting && exit 1                                                          


if [[ $letter == a ]]                                                                                                                                 
then                                                                                                                                                  
echo correct                                                                                                                                      
fi
Tomas.R
  • 715
  • 2
  • 7
  • 18
  • Context for the duplicate flag: [Canonical, language-agnostic question for `if(var != x || var != y)`?](https://meta.stackoverflow.com/questions/273262/canonical-language-agnostic-question-for-ifvar-x-var-y) – Charles Duffy Apr 08 '18 at 17:49
  • ...note the [answer by @triplee on that question](https://stackoverflow.com/a/48144901/14122), specifically going into bash. – Charles Duffy Apr 08 '18 at 17:53

1 Answers1

4

Let's take a simpler example: [[ $letter != a || $letter != b ]] No matter what letter is, one of those two tests is true. If you pick a, then $letter != b. If you pick b, then $letter != a. If you pick any other character, both are true.

You want && instead:

[[ $letter != a && $letter != b && $letter != c && $letter !=d ]] && { echo exiting; exit 1; }.

Or use =/== and use || after the test.

[[ $letter = a || $letter = b || $letter = c || $letter = d ]] || { echo exiting; exit 1; }

(In both cases, prefer an explicit if statement rather than using && or ||:

if [[ $letter != a && $letter != b ... ]]; then
    echo exiting >&2  # use standard error, not standard output
    exit 1
fi

if ! [[ $letter = a || $letter = b ... ]]; then
     echo exiting >&2  # use standard error, not standard output
     exit 1
fi

)

Much simpler, though, is to use a case statement:

case $letter in
    a|b|c|d) : ;;  # do nothing
    *) echo exiting
       exit 1
       ;;
esac
chepner
  • 497,756
  • 71
  • 530
  • 681
  • Probably ought to do the `&& { echo exiting; exit 1; }` thing even in the first code sample -- that way we still reach the `exit` even if the `echo` fails. – Charles Duffy Apr 08 '18 at 17:51
  • Thank you chepner for the answer and Charles Duffy for the links, it was very helpful. – Tomas.R Apr 08 '18 at 20:18