Definir variáveis com um nome de variável

10

O que há de errado com esse script? Estou tentando definir A1 = 1, B1 = 1, C1 = 1

LIST="A B C"
for x in $LIST
do
    "$x"1=1
done

e o resultado é:

./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found
    
por Ake Blomberg 22.08.2015 / 14:03

3 respostas

20

Uma atribuição de variável tem a forma de um nome de variável, seguido pelo sinal de igual, seguido pelo valor (opcional).

Esta é uma tarefa válida:

ABC=123

"$x"1=1 não é uma atribuição válida, porque "$x"1 não é um nome de variável. Pode ser eval uado para um nome de variável, mas não é. A casca, na verdade, acredita que é um comando.

Uma maneira de fazer o que você quer alcançar é esta:

eval "$x"1=1

Outra maneira de bash (mas não em outras shells) é:

declare "$x"1=1

Ou também (novamente bash-only):

let "$x"1=1

(Não há muita diferença no seu caso.)

Mas, como Jakuje anotado no comments , você provavelmente quer ir com arrays, se o seu shell tiver eles (ksh, bash ou zsh).

Para completar:

  • eval executa comandos arbitrários. Então, se no lado direito do sinal de igual você tiver uma variável que se expande para algum comando, esse comando será executado. O código a seguir:

    x=a
    y='$(echo hello)'
    eval "$x=$y"
    

    é equivalente a a=hello .

  • declare é um bash embutido para atribuir variáveis e não executará nenhum comando. O código a seguir:

    x=a
    y='$(echo hello)'
    declare "$x=$y"
    

    é equivalente a a='$(echo hello)' .

  • let é semelhante a declare , pois não executa comandos. Mas ao contrário de declare , let pode ser usado para operações aritméticas:

    let a="1 + 2"
    

    é equivalente a a=3 .

por 22.08.2015 / 14:47
2

O bash FAQ tem uma entrada na indireção indireta. Na maioria dos casos de uso, o que você deve realmente fazer é usar uma matriz associativa ou indexada. Você também pode usar

func_call_by_reference() { # Bash 4.3
    typeset -n ref=$1   # nameref to the variable named by the caller
    ref=( "val1" "val2" ... )  # return an array by reference
}

Veja essa entrada de Perguntas frequentes para mais opções para fazer isso e, ao mesmo tempo, evite o confuso eval quoting.

    
por 23.08.2015 / 05:18
0

Você pode usar código como o seguinte. No seu shell de código, executa "$x"1=1 como um comando porque não é uma atribuição válida de variável.

LIST="A B C"
for x in $LIST
do
    a=$(echo "$x"1)
    let $a=1
done
    
por 22.08.2015 / 15:46