Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Stéphane Chazelas wrote:

a few rules like

  • always quote variables
  • never use the -a or -o operator (use several [ commands and the && and || shell operators)

Make [ reliable with POSIX shells.

Why "never use the -a or -o operator"?

How can I do "use several [ commands and the && and || shell operators)"?

share|improve this question
up vote 13 down vote accepted

Why "never use the -a or -o operator"?

Because they may be amibiguous and hence they're not POSIX-compliant:

The XSI extensions specifying the -a and -o binary primaries and the '(' and ')' operators have been marked obsolescent. (Many expressions using them are ambiguously defined by the grammar depending on the specific expressions being evaluated.) Scripts using these expressions should be converted to the forms given below. Even though many implementations will continue to support these obsolescent forms, scripts should be extremely careful when dealing with user-supplied input that could be confused with these and other primaries and operators. Unless the application developer knows all the cases that produce input to the script, invocations like:

test "$1" -a "$2"

should be written as:

test "$1" && test "$2"

How can I do "use several [ commands and the && and || shell operators)"?

By doing multiple tests and chaining them using said operators; for example:

[ 0 -eq 0 -a \( 0 -eq 1 -o 1 -eq 1 \) ]

could be rewritten as the equivalent:

[ 0 -eq 0 ] && ([ 0 -eq 1 ] || [ 1 -eq 1 ])

or, better:

[ 0 -eq 0 ] && { [ 0 -eq 1 ] || [ 1 -eq 1 ]; }
share|improve this answer
    
thanks. (1) "the '(' and ')' operators have been marked obsolescent". Are ( and ) the operators that group commands? If they are obsolete, what are their replacement? (2) Should test "$1" -a "$2" be replaced by test "$1" && test "$2", or by ((test "$1" && test "$2"))? Don't we need the ((..))? – Tim Mar 19 at 8:22
    
@Tim See the update. (1) Yes - you can use () and {} as a replacement. (2) The first one; (()) is used for arithmetic expansion, here you want to test the exit status of the chain of tests, so either group the tests in a subshell () or in the current shell {}. – kos Mar 19 at 8:35
    
Thanks. I think my questions may go beyond this post. So I post them in a new post. – Tim Mar 19 at 8:45
    
@Tim The only reason to use the ( and ) operators is when you're using -a or -o. Since the latter are obsolescent, the former are obviously no longer needed either. – Barmar Mar 23 at 17:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.