httpinterpret
httpinterpret

Reputation: 6709

How do I play with test command properly?

[root@jiaoyou ~]# test 1 = 1 -a 0 = 1
[root@jiaoyou ~]# if [1 = 1 -a 0 = 1]then echo 1;else echo 2;fi
-bash: syntax error near unexpected token `else'

Why test doesn't give any output and the if statement fails?

Can someone point out what's wrong here?

UPDATE

Can someone illustrate how to simulate complex expressions like 1=1 and (0=1 or 1=1) with [[?

Upvotes: 2

Views: 392

Answers (3)

Gordon Davisson
Gordon Davisson

Reputation: 125818

There are several equivalent ways of doing the test you're looking for. First, essentially the way you're doing it, but with the syntax fixed (added required spaces around the parameters to the [ (aka test) command, and a ; between ] and then):

if [ 1 = 1 -a 0 = 1 ];then echo 1;else echo 2;fi

Here's a version with explicit grouping in the expression; note that the parentheses have to be escaped because they're special characters in the shell, but in this case we want them passed to the [ command as arguments:

if [ \( 1 = 1 \) -a \( 0 = 1 \) ];then echo 1;else echo 2;fi

Another version with explicit grouping, this time using two separate [ commands connected with bash's && operator (note that this can also connect other commands):

if [ 1 = 1 ] && [ 0 = 1 ];then echo 1;else echo 2;fi

And finally, a couple of examples using bash's [[ operator instead of the [ command; note that [[ isn't a command, so its expression isn't parsed as command arguments, allowing it a more intuitive syntax (e.g. allowing && and || as operators, and parentheses and !<> comparisons without escaping):

if [[ 1 = 1 && 0 = 1 ]];then echo 1;else echo 2;fi
if [[ ( 1 = 1 ) && ( 0 = 1 ) ]];then echo 1;else echo 2;fi

Some more notes/warnings: the = operator being used in all of these examples does string comparisons rather than numeric comparison (i.e. [ 1 = 01 ] is false); if you want numeric comparison use -eq instead (similarly, < and > are string comparisons, while -lt and -gt are numeric). Also, if you're comparing strings that include spaces, '[' can mistake the string for part of the expression under some circumstances (esp. if you don't have the strings wrapped in double-quotes); as far as I know [[ never has this problem. Overall, if you're using shells that support [[, it's much easier to deal with than [.

Upvotes: 1

R Samuel Klatchko
R Samuel Klatchko

Reputation: 76541

As @IgnacioVazquez-Abrams correctly states, test just sets the error code.

That said, here's a nice bash-ism for quickly checking the error value:

test [ expr ] && echo SUCCESS || echo FAIL

Due to how && and || short circuit, that will output SUCCESS or FAIL depending on whether test returns 0 or non-0.

Upvotes: 0

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 798706

Return codes are not printed; you must echo the value of $? in order to see it.

[ is a command. Just as you don't write echoHelloworld, you can't write [1 ....

Upvotes: 4

Related Questions