Do test
operators -a
and -o
short circuit?
I tried if [ 0 -eq 1 -a "" -eq 0 ]; then ...
which complained about the syntax of the second conditional. But I can't tell if that's because
-a
does not short circuit test
wants everything properly formatted before it begins and it still short circuits.The result is leading me to create a nested if
when really what I wanted was a situation where the first conditional would guard against executing the second if a particular var had not yet been set...
edit: As for why am I using obsolescent operators, the code has to work everywhere in my environment and I just found a machine where
while [ -L "$file" ] && [ "$n" -lt 10 ] && [ "$m" -eq 0 ]; do
is an infinite loop and changing to the obsolete -a
yields good behavior:
while [ -L "$file" -a "$n" -lt 10 -a "$m" -eq 0 ]; do
What should I do? The first expression works on many machines but not this machine which appears to require the second expression instead...
The || OR operator is also a short-circuit operator. Since OR evaluates to true when one or both of its operands are true , short-circuit evaluation stops with the first true . The OR operator comes in a non-short-circuit version as well: | (this is a single vertical bar.)
In Java logical operators, if the evaluation of a logical expression exits in between before complete evaluation, then it is known as Short-circuit. A short circuit happens because the result is clear even before the complete evaluation of the expression, and the result is returned.
The Python or operator is short-circuiting When evaluating an expression that involves the or operator, Python can sometimes determine the result without evaluating all the operands. This is called short-circuit evaluation or lazy evaluation. If x is truthy, then the or operator returns x . Otherwise, it returns y .
Short-circuit evaluation, minimal evaluation, or McCarthy evaluation (after John McCarthy) is the semantics of some Boolean operators in some programming languages in which the second argument is executed or evaluated only if the first argument does not suffice to determine the value of the expression: when the first ...
Per the POSIX specification for test:
>4 arguments: The results are unspecified.
Thus, barring XSI extensions, POSIX says nothing about how this behaves.
Moreover, even on a system with XSI extensions:
expression1 -a expression2
: True if both expression1 and expression2 are true; otherwise, false. The -a binary primary is left associative. It has a higher precedence than -o. [Option End]
expression1 -o expression2
: True if either expression1 or expression2 is true; otherwise, false. The -o binary primary is left associative. [Option End]
There's no specification with respect to short-circuiting.
If you want short-circuiting behavior -- or POSIX-defined behavior at all -- use &&
and ||
to connect multiple, separate test invocations.
Quoting again, from later in the document:
APPLICATION USAGE
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With