Prueba POSIX y -a

9

Revisé un script mío con checkbashisms y recibí las siguientes advertencias:

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

En la sección 4.62.4 de las especificaciones POSIX encuentro

primario -a primario Realiza un binario y de los resultados de primario y primario. El operador -a tiene prioridad sobre el operador -o.

¿Por qué son -ay se -oconsideran no portátiles?

Matteo
fuente

Respuestas:

11

No es tanto que no sea portátil, sino que no hay [implementación donde sea confiable cuando se pasan más de 4 argumentos.

Incluso en bash:

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

La sección relacionada establece:

> 4 argumentos :

Los resultados no están especificados.

[OB XSI] [Opción de inicio] En sistemas conformes a XSI, las combinaciones de primarios y operadores se evaluarán utilizando las reglas de precedencia y asociatividad descritas anteriormente. Además, las primarias binarias de comparación de cadenas '=' y "! =" Tendrán una precedencia más alta que cualquier primaria unaria. [Opción final]

-ay -odebería ser prohibido. La forma correcta es usar los operadores &&y || shell en su lugar:

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

Incluso me parece más legible.

Stéphane Chazelas
fuente
Gracias, ¿entonces la única solución sería tener dos pruebas? `if [-n" $ {ALTNAMES} "] && [-n" $ {COMMON_NAME}];
Matteo
3
No es el único, pero sin duda el mejor y recomendado como reemplazo para -ay-o
Stéphane Chazelas
Ok, muchas gracias (solo quiero decir que no hay forma de tener una sola prueba ...).
Matteo
1
Sí, podría hacerlo [ "x$ALTNAMES" != x -a "x$COMMON_NAME" != x ](aún sin especificar según POSIX pero portátil y confiable), o[ "${ALTNAMES:+x}${COMMON_NAME:+x}" = xx ]
Stéphane Chazelas