[[...]]
é uma construção de shell Korn também suportada por bash
e zsh
mas caso contrário não é um sh
um padrão (e não suportado por qualquer outro shell).
busybox
sh
é baseado em ash
que implementa um subconjunto da especificação POSIX de sh
(no código do idioma POSIX, é compatível em sua maior parte) com muito poucas extensões e, em particular, não este aqui.
Em qualquer caso, ao escrever um script sh
, você deve se ater à especificação POSIX sh
. Os scripts que usam [[...]]
devem invocar ksh
, bash
ou zsh
explicitamente. bash
também é um shell compatível principalmente com POSIX sh, mas com muito mais extensões (incluindo essa).
O teste para x ser não-vazio e, em seguida, ser igual a production
faz pouco sentido. Se x == production
, então obviamente não está vazio.
Faça comparações de strings com o shell POSIX e utilitários, você tem algumas opções, as mais óbvias neste caso são:
-
o utilitário [
, também conhecido como test
, geralmente construído no shell:
if [ "$var" = production ]; then
echo PROD
fi
-
a construção case
:
case $var in
production) echo PROD;;
"") echo EMPTY;;
*) echo non-PROD;;
esac
Agora, você pode querer verificar se a variável é definida (em oposição a não vazia), antes de desreferenciar, no caso em que a opção nounset
foi ativada (com set -u
ou set -o nounset
ou com #! /bin/sh -u
como a linha she-bang), caso contrário, um [ "$ENV" = production ]
causaria a saída do shell se $ENV
não estivesse definido. Para fazer isso, você faria:
if [ "${var+set}" = set ] && [ "$var" = production ]; then
echo PROD
fi
(você deve evitar que o operador -a
[
AND esteja obsoleto e não seja confiável).
Embora uma maneira melhor e mais canônica de fazer isso seja:
if [ "${var-}" = production ]; then
echo PROD
fi
nounset
não é acionado em ${var+string}
ou ${var-string}
expansões. ${var-}
expande para o conteúdo de $var
se a variável estiver configurada ou a sequência vazia de outra forma.
Algumas outras notas:
$ENV
é uma variável especial para sh
. Quando iniciado interativamente, é considerado como o caminho para um arquivo para ler as inicializações (o equivalente a ~/.bashrc
para bash
). Você não deve usá-lo para outros fins.
Você descobrirá que alguma literatura antiga de script shell do Unix recomenda usar [ "x$var" = xproduction ]
ou [ production = "x$var" ]
para fazer a comparação de strings. Isso foi para superar erros em algumas versões antigas do utilitário [
e test
que foram confundidos por alguns valores de $var
como !
, (
ou -n
. Não deveria ser necessário em sistemas modernos, mas algo para ter em mente para sistemas muito antigos. Em qualquer caso, a construção case
não tem esse tipo de problema.
Outros utilitários POSIX que podem fazer comparação de string incluem expr
e awk
.
awk_equal() { awk 'BEGIN{exit(!(""ARGV[1] == ""ARGV[2]))}' "$1" "$2"; }
expr_equal() { expr "x $1" = "x $2" > /dev/null; }
if awk_equal "$var" production; then
echo PROD
fi
if expr_equal "$var" production; then
echo PROD
fi
Observe a necessidade de pré-adicionar ""
aos valores com awk
para garantir que recebamos uma comparação de string (caso contrário, 1
seria considerado igual a 01
ou 1e0
) e x
em expr
pelo mesmo motivo, mas também para evitar problemas com valores sendo expr
de operadores.
Com os operadores awk
e expr
(pelo menos POSIXly), eles não são realmente igualdade , mas um teste para saber se os dois operandos têm ordem de classificação igual, que pode não ser necessariamente a mesma coisa. Por exemplo, em may system, expr_equal ② ③
retorna true, porque nem ② nem ③ possuem uma ordem de classificação definida. Algumas implementações awk
como gawk
, mawk
e busybox awk
ignoram esse requisito POSIX e fazem uma simples comparação byte a byte.
De qualquer forma, não consigo pensar em nenhuma boa razão para você preferir aqueles com mais de [
ou case
aqui.