Search code examples
posixshundefined-behaviorlogical-operators

Shell scripts: undefined -a, -o switch behavior


According to the shellcheck wiki:

-a and -o to mean AND and OR in a [ .. ] test expression is not well defined. They are obsolescent extensions in POSIX and their behavior is almost always undefined.

Any idea what wrong can happen?


Solution

  • See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html#tag_20_128_16 for a discussion about the problems -a and -o can raise. In general, how the expression is parsed becomes dependent on what any parameters expand to. Consider the following test:

    test "$1" -a "$2"
    

    Depending on the value of $1, this could be either

    # Unspecified behavior
    # With three arguments, the first "!", the second argument
    # must be a unary primary like -n or -f.
    test "!" -a "$2"
    

    or

    test "foo" -a "$2"  # Test that "foo" and "$2" are non-zero length strings
    

    If $1 is !, test will treat that as the negation operator, not a string to whose length should be checked.

    Also, test is only well-defined for 4 or fewer arguments; -a and -o usually result in 5 or more arguments being passed to test.