andrea
andrea

Reputation: 535

checking if argument passed equals a string in bash script

Little explanation necessary: why the hell does this doesn't work?

#!/bin/bash

ker=$1
if [ "$ker" != "iso" ] || [ "$ker" != "om" ] || [ "$ker" != "constbeta" ] ; then
 printf " allowed kernels: iso, om, constbeta \n"
 exit
fi
wait
echo 'anisotropy kernel: ', "$ker"

I have also tried

#!/bin/bash

ker="$1"
if [ $ker != "iso" ] || [ $ker != "om" ] || [ $ker != "constbeta" ] ; then
 printf " allowed kernels: iso, om, constbeta \n"
 exit
fi
wait
echo 'anisotropy kernel: ', "$ker"

I call it like this: $ ./script.sh iso
and I've even tried like this (though I think this doesn't make sense with the scripts above): $ ./script.sh "iso"
I always get allowed kernels: iso, om, constbeta
Many thanks to those who can spot the error.

Upvotes: 1

Views: 7440

Answers (2)

ghoti
ghoti

Reputation: 46826

You've got an irrational condition...

if [ "$ker" != "iso" ] || [ "$ker" != "om" ] || [ "$ker" != "constbeta" ] ; then

If $ker is "iso", then it is not "om" and the condition matches. If $ker is "om" then it is not "iso" and the condition matches. What you want is to OR a list of positive checks and have an "else" condition, rather than OR the negative checks.

if [ "$ker" = "iso" ] || [ "$ker" = "om" ] || [ "$ker" = "constbeta" ] ; then
    : do something useful
else
    : report error
fi

Or, since you're in bash, you could use a "simpler" condition:

if [[ "$ker" =~ ^(iso|om|constbeta)$ ]]; then

Though if you like you could use other constructs:

case "$ker" in
  iso|om|constbeta)
    : this catches our "good" values
    ;;
  *)
    echo "Error" >&2
    exit 1
    ;;
esac

This has the possible benefit of being POSIX compliant.

Upvotes: 1

Nahuel Fouilleul
Nahuel Fouilleul

Reputation: 19305

because of the logical or ||, you should use and && otherwise the condition is always true thinking to the negation string can't be equals to the three value.

Upvotes: 2

Related Questions