Si su $VARIABLE
es una cadena que contiene espacios u otros caracteres especiales, y se utilizan corchetes individuales (que es un atajo para el test
comando), entonces la cadena se puede dividir en varias palabras. Cada uno de estos se trata como un argumento separado.
Para que una variable se divida en muchos argumentos :
VARIABLE=$(/some/command);
# returns "hello world"
if [ $VARIABLE == 0 ]; then
# fails as if you wrote:
# if [ hello world == 0 ]
fi
Lo mismo será cierto para cualquier llamada de función que ponga una cadena que contenga espacios u otros caracteres especiales.
Arreglo fácil
Envuelva la salida variable entre comillas dobles, forzándola a permanecer como una cadena (por lo tanto, un argumento). Por ejemplo,
VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
# some action
fi
Simple como eso. Pero pase a "También tenga cuidado ..." a continuación si tampoco puede garantizar que su variable no sea una cadena vacía, o una cadena que no contenga más que espacios en blanco.
O, una solución alternativa es usar corchetes dobles (que es un atajo para el new test
comando).
Sin embargo, esto solo existe en bash (y aparentemente korn y zsh), por lo que puede no ser compatible con shells predeterminados llamados por /bin/sh
etc.
Esto significa que en algunos sistemas, podría funcionar desde la consola, pero no cuando se llama a otra parte, como desdecron
, dependiendo de cómo esté configurado todo.
Se vería así:
VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
# some action
fi
Si su comando contiene corchetes dobles como este y obtiene errores en los registros pero funciona desde la consola, intente cambiar el [[
por una alternativa sugerida aquí, o asegúrese de que todo lo que se ejecute en su script use un shell que sea compatible con [[
aka new test
.
También ten cuidado con el [: unary operator expected
error
Si ve el error "demasiados argumentos", es probable que obtenga una cadena de una función con salida impredecible. Si también es posible obtener una cadena vacía (o toda la cadena de espacios en blanco), esto se trataría como cero argumentos incluso con la "solución rápida" anterior, y fallaría con[: unary operator expected
Es el mismo 'problema' si estás acostumbrado a otros idiomas: no esperas que el contenido de una variable se imprima efectivamente en el código como este antes de que se evalúe.
Aquí hay un ejemplo que evita [: too many arguments
los [: unary operator expected
errores y los errores: reemplazar la salida con un valor predeterminado si está vacío (en este ejemplo, 0
), con comillas dobles alrededor de todo:
VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
# some action
fi
(aquí, la acción ocurrirá si $ VARIABLE es 0, o está vacío. Naturalmente, debe cambiar el 0 (el valor predeterminado) a un valor predeterminado diferente si se desea un comportamiento diferente)
Nota final: dado que [
es un atajo para test
, todo lo anterior también es cierto para el error test: too many arguments
(y también test: unary operator expected
)