Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
add comment

2 Answers

up vote 5 down vote accepted

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.

share|improve this answer
    
Thanks, so the only solution would be to have two tests? `if [ -n "${ALTNAMES}" ] && [ -n "${COMMON_NAME} ] ; –  Matteo Dec 7 '12 at 7:52
2  
Not the only one but certainly the best and recommended as a replacement for -a and -o –  Stephane Chazelas Dec 7 '12 at 8:27
    
Ok many thanks (with only I meant that there is no way to have a single test ...). –  Matteo Dec 7 '12 at 8:40
    
Yes, you could do [ "x$ALTNAMES" != x -a "x$COMMON_NAME" != x ] (still unspecified as per POSIX but portable and reliable), or [ "${ALTNAMES:+x}${COMMON_NAME:+x}" = xx ] –  Stephane Chazelas Dec 7 '12 at 10:40
add comment

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

share|improve this answer
add comment

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.