como verificar a existência da variável e comparar com a cadeia no busybox?

3

Eu quero usar algo assim

if [[ ! -z "$ENV" && $ENV == 'production' ]]; then echo "production"; else echo "dev"; fi

mas no BusyBox não funciona: (

sh: 1: [[: not found

Parece que qualquer combinação AND ou OR não funciona na instrução IF no busybox

    
por user1016265 20.07.2016 / 13:08

2 respostas

3

Você pode usar a sintaxe [ mais antiga

if [ -n "$ENV" -a "$ENV" = 'production' ]

(note que usei -n em vez de ! -z porque é mais fácil, mas é a mesma coisa).

Ou podemos simplificar para uma sintaxe ainda mais antiga, forçando a string a ter um valor:

if [ "x$ENV" = 'xproduction' ]

Finalmente, o teste -n pode não ser realmente necessário e você pode fazer isso

if [ "$ENV" = 'production' ]
    
por 20.07.2016 / 14:12
6

[[...]] é 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.

    
por 20.07.2016 / 14:52