Como eu eval dois comandos?

2

Se eu executar isso:

echo "echo 'a'; echo 'b'"

Ele produz uma string que eu posso executar e funciona - ecoa a\nb\n .

No entanto, isso não funciona:

$(echo "echo 'a'; echo 'b'")

Por que não? Não funciona para nenhum comando, não apenas para o eco. Como executo uma string contendo dois ou mais comandos?

    
por Benubird 16.05.2014 / 14:42

1 resposta

5

Em $(echo "echo 'a'; echo 'b'") , o shell vê uma substituição de comando. E é isso. Então, esse será um comando simples cujos argumentos são resultantes do operador split + glob na expansão da substituição do comando.

O shell pegará a saída do comando echo "echo 'a'; echo 'b'" , nesse caso echo 'a'; echo 'b'\n , removerá os caracteres de nova linha à direita para que se torne echo 'a'; echo 'b' , divida isso de acordo com o valor da variável $IFS .

Se $IFS não tiver sido alterado de seu padrão, serão 4 palavras: echo , 'a'; , echo e 'b' . Cada uma dessas palavras estará sujeita a globbing. Aqui, nenhum contém caracteres globbing, então essas palavras permanecerão como estão.

Portanto, temos 4 argumentos para executar um comando simples. O primeiro argumento será usado para derivar o comando a ser executado. echo está embutido na maioria dos shells. Portanto, o shell chamará seu echo integrado com esses 4 argumentos.

echo ignora seu primeiro (0º) argumento e exibe os outros separados por caracteres de espaço e finalizados por um caractere de nova linha. Algumas implementações de echo expandem sequências de escape de barra invertida, mas não há nenhuma aqui. Então, echo irá produzir:

'a'; echo 'b'\n

Se você quiser avaliar, ou seja, se quiser que a string seja interpretada como código de shell, use eval :

eval "echo 'a'; echo 'b'"

Isso também é reconhecido como um comando simples. Por causa das cotações, o shell vê duas "palavras": eval e echo 'a'; echo 'b' . Novamente, eles comporão os argumentos para o comando que é derivado do primeiro.

Aqui o comando é o comando eval builtin do shell. Novamente, eval ignora seu primeiro argumento. O que ele faz é concatenar seus outros argumentos (aqui há apenas um) com espaços e interpretar a string resultante como código shell. Ao interpretar

echo 'a'; echo 'b'

O shell vê um ; sem aspas, que delimita os comandos. O primeiro é tratado como um comando simples que acaba chamando echo com dois argumentos ... etc.

    
por 16.05.2014 / 15:10