72

I'm not sure how to do an if with multiple tests in shell. I'm having trouble writing this script:

echo "You have provided the following arguments $arg1 $arg2 $arg3"
if [ "$arg1" = "$arg2" && "$arg1" != "$arg3" ]
then
    echo "Two of the provided args are equal."
    exit 3
elif [ $arg1 = $arg2 && $arg1 = $arg3 ]
then
    echo "All of the specified args are equal"
    exit 0
else
    echo "All of the specified args are different"
    exit 4
fi

The problem is I get this error every time:

./compare.sh: [: missing `]' command not found

1
  • 10
    Quite a few commentators have suggested you use [[ rather than [ but that makes your script bash-specific. You'll have fewer maintenance and portability issues if you can stick to plain old Bourne shell (sh) syntax. Commented Mar 1, 2010 at 22:01

6 Answers 6

57

Josh Lee's answer works, but you can use the "&&" operator for better readability like this:

echo "You have provided the following arguments $arg1 $arg2 $arg3"
if [ "$arg1" = "$arg2" ] && [ "$arg1" != "$arg3" ]
then 
    echo "Two of the provided args are equal."
    exit 3
elif [ $arg1 = $arg2 ] && [ $arg1 = $arg3 ]
then
    echo "All of the specified args are equal"
    exit 0
else
    echo "All of the specified args are different"
    exit 4 
fi
Sign up to request clarification or add additional context in comments.

Comments

42

sh is interpreting the && as a shell operator. Change it to -a, that’s [’s conjunction operator:

[ "$arg1" = "$arg2" -a "$arg1" != "$arg3" ]

Also, you should always quote the variables, because [ gets confused when you leave off arguments.

Comments

9

I have a sample from your code. Try this:

echo "*Select Option:*"
echo "1 - script1"
echo "2 - script2"
echo "3 - script3 "
read option
echo "You have selected" $option"."
if [ $option="1" ]
then
    echo "1"
elif [ $option="2" ]
then
    echo "2"
    exit 0
elif [ $option="3" ]
then
    echo "3"
    exit 0
else
    echo "Please try again from given options only."
fi

This should work. :)

2 Comments

Gawd this looks quirky to me. Why no then after else? It may actually not be quirky, but that's how it looks, compared to C.
space is required after $option and before = to run it fine, else every time 1
8

Use double brackets...

if [[ expression ]]

4 Comments

To note, this is a solution because the [[ construct is built into the shell while [ is another name for the test command and hence is subject to its syntax -- see man test
Technically, [ is a shell builtin, but [[ is a shell keyword. That’s the difference.
So see the results of the bash commands type [, type [[, help [ and help [[.
@JoshLee no, there is a file called /usr/bin/[
5

Change [ to [[, and ] to ]].

1 Comment

Better yet, change '[' to 'test'
2

This is working for me,

 # cat checking.sh
 #!/bin/bash
 echo "You have provided the following arguments $arg1 $arg2 $arg3"
 if [ "$arg1" = "$arg2" ] && [ "$arg1" != "$arg3" ]
 then
     echo "Two of the provided args are equal."
     exit 3
 elif [ $arg1 == $arg2 ] && [ $arg1 = $arg3 ]
 then
     echo "All of the specified args are equal"
     exit 0
 else
     echo "All of the specified args are different"
     exit 4
 fi

 # ./checking.sh
 You have provided the following arguments
 All of the specified args are equal

You can add set -x in script to troubleshoot the errors.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.