9

I checked a script of mine with checkbashisms and I got the following warnings:

possible bashism in check_ssl_cert line 821 (test -a/-o):
if [ -n "${ALTNAMES}" -a -n "${COMMON_NAME}" ] ; then

In section 4.62.4 of the POSIX specs I find

primary -a primary Performs a binary and of the results of primary and primary. The -a operator has precedence over the -o operator.

Why are -a and -o considered non-portable?

Matteo
  • 9,796
  • 4
  • 51
  • 66

2 Answers2

11

It's not so much that it is not portable, but that there's no [ implementation where it is reliable when passed more than 4 arguments.

Even in bash:

$ ALTNAMES='='  bash -c '[ -n "${ALTNAMES}" -a -n "${COMMON_NAME}" ]'
bash: line 0: [: too many arguments

The related section states:

>4 arguments:

The results are unspecified.

[OB XSI] [Option Start] On XSI-conformant systems, combinations of primaries and operators shall be evaluated using the precedence and associativity rules described previously. In addition, the string comparison binary primaries '=' and "!=" shall have a higher precedence than any unary primary. [Option End]

-a and -o should be banned. The right way is to use the && and || shell operators instead:

if [ -n "$foo" ] && [ -n "$bar" ]; then

I even find it more legible.

2

Because they are an XSI extension, which may or not be implemented. See: http://pubs.opengroup.org/onlinepubs/009695399/utilities/test.html