tags:

views:

43

answers:

1

What is the order in which the test or [ expressions are evaluated in a bash script? Is it the same as the order in which they are written? Are they all evaluated?

In the following example:

if [ expr1 -a -n expr2 ]

will expr2 be evaluated if expr1 is false?

+5  A: 

It's been a long time since I used that particular syntax. Nowadays, I prefer:

if [[ expr1 && -n expr2 ]]

since I know that these are short-circuited. The bash man page specifically states:

The && and || operators do not evaluate expression2 if the value of expression1 is sufficient to determine the return value of the entire conditional expression.

It doesn't appear to state clearly one way or the other for the [ and test variant (using -a).

However, in the interests of furthering your knowledge and mine (and an indication as to why open source is a good thing), I went trolling through the bash source code.

It turns out that it's not short-circuited in that case. The particular pieces of code are (compressed a bit for readability):

static int or() {
    int value, v2;
    value = and();
    if (pos < argc && argv[pos][0] == '-'
      && argv[pos][1] == 'o' && !argv[pos][2])
    {
        advance (0);
        v2 = or();
        return (value || v2);
    }
    return (value);
}

static int and() {
    int value, v2;
    value = term();
    if (pos < argc && argv[pos][0] == '-'
      && argv[pos][1] == 'a' && !argv[pos][2])
    {
        advance (0);
        v2 = and();
        return (value && v2);
    }
    return (value);
}

You can see in both those cases that it continues to interpret the expressions regardless of the state of the first expression.

That was from bash 2.5 but I've just checked the 4.1 source as well and it hasn't changed. Source was pulled straight from the horse's mouth.

So. bottom line: it appears that all sub-expressions are evaluated when using -a and -o with test or [.

paxdiablo
Holy... bash! You're good :)
Tom