Atribuição variável fora da instrução case

7

Em muitas linguagens, é possível atribuir o resultado de uma instrução case / switch a uma variável, em vez de repetir a atribuição da variável várias vezes dentro da instrução case. É possível fazer algo assim no shell Bash?

color_code=$(case "$COLOR" in
  (red)    1;;
  (yellow) 2;;
  (green)  3;;
  (blue)   4;;
esac)

(Ou, como um aparte, em alguma outra casca?)

    
por iconoclast 31.07.2014 / 06:30

2 respostas

5

A construção variable=$(...) receberá a saída padrão de qualquer comando em $(...) e a atribuirá a variable . Assim, para obter variable atribuído da maneira desejada, os valores devem ser enviados para a saída padrão. Isso é feito facilmente com o comando echo :

color_code=$(case "$COLOR" in
  red)    echo 1;;
  yellow) echo 2;;
  green)  echo 3;;
  blue)   echo 4;;
esac)

Isso funcionará no bash , bem como em todos os outros POSIX shells.

Os Parêntesis Esquerdos Opcionais

De acordo com o padrão POSIX, os parentes esquerdos em uma instrução case são opcionais e o seguinte também funciona:

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Como Gilles aponta nos comentários, nem todos os shells aceitam ambas as formas em combinação com $(...) : para uma tabela impressionantemente detalhada de compatibilidade, veja " $ () "substituição de comando vs. incorporado") ".

    
por 31.07.2014 / 06:45
2

color_code=$(…) atribui a saída do comando à variável color_code , com novas linhas finais removidas. Então você precisa produzir alguma saída. O código que você escreveu tenta executar 1 como um comando.

Você pode usar esse idioma. Observe que color_code estará vazio se $COLOR não for nenhum dos valores suportados.

color_code=$(case "$COLOR" in
  (red)    echo 1;;
  (yellow) echo 2;;
  (green)  echo 3;;
  (blue)   echo 4;;
esac)

Mas não é muito idiomático. A linguagem shell é voltada para combinações simples de comandos simples. Essa grande substituição de comandos é inadequada. A substituição de comando cria um subshell, que é mais lento que o método simples:

case "$COLOR" in
  red)    color_code=1;;
  yellow) color_code=2;;
  green)  color_code=3;;
  blue)   color_code=4;;
esac

A principal diferença semântica entre as duas abordagens é que $(…) cria uma subshell, de forma que qualquer atribuição, saída, redirecionamento, etc., que seja executada dentro dela, não tem nenhum efeito externo.

    
por 01.08.2014 / 01:49