1

I am writing a bash shell script at the moment and one of the specifications is that I need to print an error message if the first argument, $1, is not -e or -d, this is what I have done:

if [ "$1" != "-e" ] || [ "$1" != "-d" ]; then
        echo "Error: First argument must be either -e or -d"
        exit 1
fi

this does not seem to work however, as even if i used -e or -d for the first argument, this error message is still printed. What am I doing wrong and how do I fix this?

ilkkachu
  • 138,973

2 Answers2

1

If $1 is -d, the first condition is true. If $1 is -e, the second condition is true. If it's anything else, both are true. Since you joined them with || (or), the then branch of the if is taken if either is true. Therefore, the then branch is always taken.

You need to use if [ "$1" != "-e" ] && [ "$1" != "-d" ] to take the then branch only if $1 is not -e and is not -d.

ilkkachu
  • 138,973
1
case $1 in
    -d) ;; # nothing to do
    -e) ;; # nothing to do
    *)
        echo 'Error: First argument must be either -e or -d' >&2
        exit 1
esac

This would trigger the exit 1 if $1 is anything other than -d or -e.

Alternatively, set a flag depending on the option used and the act on it (I tend to separate parsing the command line options from acting on them):

case $1 in
    -d) dflag=1 ;;
    -e) dflag=0 ;;
    *)
        echo 'Error: First argument must be either -e or -d' >&2
        exit 1
esac

# Getting here means:
#     - $1 was either -d or -e
#     - $dflag will show which one it was

if [ "$dflag" -eq 1 ]; then
    # act on -d option
else
    # act on -e option
fi

As ilkkachu has already elucidated, your issue (apart from the missing double quote) is one of logic (boolean operations). Above, I'm just showing another way of doing the operation. case...esac statements are often used to process command line options.

Kusalananda
  • 333,661