Usando o comando eval duas vezes

2

Suponha que:

a=b; b=c; c=d

Em seguida, eval echo \$$a produz a saída:

c

Se quisermos extrair a saída d usando apenas a entrada a , tentei da seguinte maneira:

(i) eval echo \$(eval echo \$$a) produz o erro:

syntax error near unexpected token '('

(ii) eval echo \$\(eval echo \$$a\) produz a saída:

c

Não consigo entender por que a fuga que cortou o colchete eliminou o erro.

Além disso, alguém poderia explicar por que não recebi a saída como d na segunda instância?

    
por MathMan 10.11.2016 / 21:53

3 respostas

4

Primeiro, uma palavra de cautela:

Do ponto de vista de segurança, é uma péssima idéia usar eval em qualquer script de shell a menos que você saiba exatamente o que está fazendo. (E, mesmo assim, praticamente não há instâncias em que essa é realmente a melhor solução.) Como um iniciante no shell de scripts, por favor, esqueça que eval existe mesmo.

Para ler mais, consulte questões de segurança e comando do Eval .

Para obter a saída d , você pode usar:

eval echo \$${!a}

Ou:

eval eval echo \\$\$$a

Onde você errou, passou os caracteres dos parênteses sem escape para echo . Se eles forem precedidos por um $ sem aspas, será a substituição do comando. Mas se o $ for citado e não os parênteses, não é uma sintaxe de shell válida.

    
por 10.11.2016 / 22:37
3

Análises aninhadas são uma coisa confusa.

Primeiro,

eval echo \$\(eval echo \$$a\)

faz com que o intérprete avalie o seguinte:

echo $(eval echo $b)

A interpolação do comando interno mais interno (ou seja, $(eval echo $b) ) resulta em:

echo c

Qual é o resultado:

c

Se você quiser que as avaliações aninhadas sejam avaliadas corretamente (e eu recomendo não usando eval para em todos os ), você terá que ficar bem estranho. Veja outras respostas para exemplos.

    
por 10.11.2016 / 22:36
1

Você pode obter a saída esperada d com o  seguinte:

eval echo \$$(echo ${!a})

${!a} é uma expansão de nome de variável bash que fornece c com seus valores. Consulte o manual do bash .

    
por 10.11.2016 / 22:36