Se $VARIABLE
for uma sequência contendo espaços ou outros caracteres especiais, e colchetes simples forem usados (que é um atalho para o test
comando), a sequência poderá ser dividida em várias palavras. Cada um deles é tratado como um argumento separado.
Para que uma variável seja dividida em vários argumentos :
VARIABLE=$(/some/command);
# returns "hello world"
if [ $VARIABLE == 0 ]; then
# fails as if you wrote:
# if [ hello world == 0 ]
fi
O mesmo vale para qualquer chamada de função que coloque uma string contendo espaços ou outros caracteres especiais.
Correção fácil
Coloque a saída variável entre aspas duplas, forçando-a a permanecer como uma sequência (portanto, um argumento). Por exemplo,
VARIABLE=$(/some/command);
if [ "$VARIABLE" == 0 ]; then
# some action
fi
Simples assim. Mas pule para "Também tome cuidado ..." abaixo se você também não puder garantir que sua variável não será uma sequência vazia ou uma sequência que não contenha nada além de espaço em branco.
Ou, uma correção alternativa é usar colchetes duplos (que é um atalho para o new test
comando).
Porém, isso existe apenas no bash (e aparentemente korn e zsh) e, portanto, pode não ser compatível com os shells padrão chamados por /bin/sh
etc.
Isso significa que em alguns sistemas, ele pode funcionar no console, mas não quando chamado em outro lugar, como emcron
, dependendo de como tudo está configurado.
Seria assim:
VARIABLE=$(/some/command);
if [[ $VARIABLE == 0 ]]; then
# some action
fi
Se o seu comando contiver colchetes duplos como esse e você receber erros nos logs, mas funcionar no console, tente trocar a [[
alternativa sugerida aqui ou verifique se o que executa o script usa um shell que suporte[[
aka new test
.
Também tenha cuidado com o [: unary operator expected
erro
Se você estiver vendo o erro "muitos argumentos", é provável que esteja obtendo uma string de uma função com saída imprevisível. Se também for possível obter uma string vazia (ou toda a string de espaço em branco), isso seria tratado como zero argumento, mesmo com a "correção rápida" acima, e falharia com[: unary operator expected
É a mesma 'pegadinha' se você estiver acostumado a outros idiomas - não espera que o conteúdo de uma variável seja efetivamente impresso no código como este antes de ser avaliado.
Aqui está um exemplo que impede [: too many arguments
os [: unary operator expected
erros e: substituir a saída por um valor padrão se estiver vazio (neste exemplo 0
), com aspas duplas em volta da coisa toda:
VARIABLE=$(/some/command);
if [ "${VARIABLE:-0}" == 0 ]; then
# some action
fi
(aqui, a ação ocorrerá se $ VARIABLE for 0 ou vazio. Naturalmente, você deve alterar 0 (o valor padrão) para um valor padrão diferente se um comportamento diferente for desejado)
Nota final: como [
é um atalho para test
, tudo acima também é verdadeiro para o erro test: too many arguments
(e também test: unary operator expected
)