Para la versión anterior de la respuesta, vea la segunda parte de esta respuesta. Si desea conocer los detalles, siga leyendo
La causa del problema
En la pregunta en sí, se informa que OP ve too many arguments error
, que cuando se prueba bash
no parece ser el caso:
$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected
Con lo /bin/sh
que en realidad está vinculado a /bin/dash
Ubuntu, el error se informa de la siguiente manera:
$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator
Y el independiente /bin/test
también:
$ /usr/bin/test $1 != ''
/usr/bin/test: missing argument after ‘’
Nota al margen: si se pregunta qué es /usr/bin/test
y por qué estoy usando bash
y sh
, entonces debe saber que [
es un alias para el test
comando, que también existe como ejecutable independiente o más comúnmente, como shell incorporado, que es lo que cada shell usará primero . En cuanto a las if
declaraciones, operan en las estatuas de salida de los comandos, por lo tanto, por qué [
y test
son comandos, y todo lo demás son argumentos para esos comandos: el orden incorrecto de esos argumentos de la línea de comandos conduce a errores.
Volviendo al tema: no está claro cómo OP obtuvo el error no relacionado. Sin embargo, en los 3 casos el problema es el mismo: la variable no establecida se tratará como vacía, por lo tanto, lo que el shell ve con estas variables no citadas es
[ != '' ]
que rompe la sintaxis que test
entiende. ¿Recuerdas lo que dije sobre el orden incorrecto de los argumentos de la línea de comandos? Por eso es importante citar. Habilitemos la salida de diagnóstico y veamos qué shell se ejecuta:
$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ]
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars
Mejor manera de probar variables no establecidas
Un enfoque muy frecuente que ves alrededor es este:
if [ "x$var1" == "x" ] && [ "x$var2" == "x" ];
then
echo "both variables are null"
fi
Para citar a Gilles :
En ["x $ 1" = "x"], el prefijo x asegura que x "$ 1" no pueda parecer un operador, por lo que la única forma en que el shell puede analizar esta prueba es tratando a = como un operador binario.
Presumiblemente, esto debería ser bastante portátil ya que los he visto en /bin/sh
scripts. También se puede combinar como en
if [ "x${var1}${var2}" == "x" ]; then
...
fi
Por supuesto, podríamos usar la -z
bandera, sin embargo, según la investigación en algunos shells, particularmente ksh88 (según Stephane Chazelas ), esta bandera es defectuosa.
Ver también