Bash: substituição de comando com múltiplos comandos unset / export

3

Estou tentando remover algumas variáveis e exportar outras usando a substituição de comandos. Isso funciona:

$(echo "
    export TEST_A=1
    export TEST_B=2
")

E isso também:

$(echo "
    unset TEST_A
    unset TEST_B
")

No entanto, isso falha com o Bash 4.3.30 (1) -release no OSX e no Debian Jessie:

$(echo "
    unset TEST_A
    export TEST_B=1
")
# bash: unset: 'TEST_B=1': not a valid identifier

Este é um comportamento esperado e como se pode desconfigurar e exportar múltiplas variáveis usando a substituição de comandos?

Para fornecer algum contexto: aqui está o problema relacionado no boot2docker .

    
por skozin 28.01.2015 / 15:43

1 resposta

7

Em:

$(echo "
  export TEST_A=1
  export TEST_B=2
")

sendo $(...) , apenas uma expansão é analisada como um comando simples.

Para que a expansão $(...) seja submetida ao operador split + glob. A saída de echo é aparada de seus caracteres de nova linha à direita e dividida em várias palavras em caracteres IFS (nova linha, espaço e tabulação por padrão):

  • export
  • TEST_A=1
  • export
  • TEST_B=2

E cada palavra sofre globbing. Aqui eles se expandem para si mesmos, pois não contêm caracteres curinga. Então, depois de globbing, ainda temos a mesma lista de quatro strings.

O comando a ser executado é derivado do primeiro. Aqui export e todas essas cadeias são passadas como argumentos para esse comando. Então, aqui, é como se você tivesse escrito:

export TEST_A=1 export TEST_B=2

Portanto, você está exportando a variável TEST_A com o valor 1, a variável export sem alterar seu valor e a variável TEST_B com valor 2.

No último, você está executando:

unset TEST_A export TEST_B=1

Se você quiser que a saída de echo seja tratada como código de shell para interpretar, é aí que você deseja usar eval e não usar o split + glob operador (cite sua substituição de comando):

eval "$(echo "
  unset TEST_A
  export TEST_B=1
")"

Esse também é um comando simples . Duas strings: eval e <newline><spaces>unset TEST_A<newline><spaces>export TEST_B=1 .

eval avalia o conteúdo de seus argumentos como código shell. Portanto, ele executa essas duas linhas de comando do shell: unset TEST_A e export TEST_B=1 (novamente, dois comandos simples ).

    
por 28.01.2015 / 15:54