É possível usar a indireção para configurar variáveis?

7

Por exemplo o próximo script exibirá Hello devido à regra ${! .

A=B
B=Hello
echo ${!A}

Mas como posso definir valor para variável com nome indireto? O uso direto do sinal ! não funciona:

A=B
!A=Hello # here is tricky line
echo $B

Eu sei que há um truque com o uso do arquivo temporário, mas estou interessado em usar indireção, não como

A=B
echo "$A=Hello" > 1.tmp
. 1.tmp
echo $B
    
por Sergey Grinev 18.03.2013 / 17:04

3 respostas

5

Outra maneira de experimentar:

$ A=B
$ read $A <<< 81
$ echo "$B"
81

Mas há um risco de segurança (!) como acontece com todos esses métodos (também declare / typeset e, é claro, eval ). Nesse caso, deve-se controlar o lado esquerdo (o valor de $A ), em outras palavras, pelo menos em bash , a variável $A não deve conter entrada controlada pelo usuário, por exemplo, um arquivo de entrada, etcetera ...

Se seu shell não suportar uma string here ( <<< ), você também pode usar um here-document:

A=B
read $A << EOF
82
EOF
echo "$B"
    
por 18.03.2013 / 17:43
11

Você pode fazer isso com o typeset builtin:

$ A=B
$ typeset $A=42
$ echo $B
42

Ou usando declare :

$ declare $A=1
$ echo $B
1
    
por 18.03.2013 / 17:31
8

Seguindo a indireta ao obter o valor de uma variável

A maneira portátil é usar eval . Você precisa prestar atenção à cotação para que os caracteres especiais no valor não sejam avaliados quando não deveriam. A maneira mais fácil é armazenar o novo valor em uma variável intermediária e atribuir o valor dessa variável.

A=B
tmp='stuff with special characters or whatever…'
eval $A=\$tmp

O argumento para eval é B=$tmp , uma atribuição direta. Você não precisa de aspas duplas em torno de $tmp , mesmo que contenha espaços em branco ou caracteres globbing, porque eles não são expandidos em uma atribuição.

Se você quiser criar uma variável de ambiente, use export . No bash ou ksh ou zsh, você pode usar typeset para fazer uma variável local ( declare é sinônimo no bash). Novamente, você deve usar uma variável intermediária para que os caracteres especiais não sejam desconfigurados. Note que, exceto em zsh, você precisa colocar aspas duplas em torno da expansão da variável, porque isso não é uma atribuição, mas uma construção que leva um argumento que parece ser uma atribuição.

export $A="$tmp"
    
por 19.03.2013 / 01:17

Tags