変数名で変数を定義する


11

このスクリプトの何が問題になっていますか?A1 = 1、B1 = 1、C1 = 1を定義しようとしています

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

結果は次のとおりです。

./x.: line 7: A1=1: command not found
./x.: line 7: B1=1: command not found
./x.: line 7: C1=1: command not found

1
このようにbashで変数を作成できるとは思いません。これが配列です。
Jakuje

3
を使用しeval "$x"1=1ます。Jakujeが述べたように、配列はおそらくこの場合により適しています。
Andrea Corbellini、2015

@AndreaCorbellini答えとして書いてください。
Sparhawk、2015

回答:


21

変数の割り当ては、変数名、等号、値(オプション)の順になっています。

これは有効な割り当てです。

ABC=123

"$x"1=1"$x"1変数名ではないため、有効な割り当てではありません。それはかもしれevalの変数名にuatedが、そうではありません。実際、シェルはそれがコマンドであると信じています。

達成したいことを行う1つの方法は次のとおりです。

eval "$x"1=1

bashの他の方法(他のシェルではない)は次のとおりです。

declare "$x"1=1

または(再びbashのみ):

let "$x"1=1

(あなたのケースでは大きな違いはありません。)

しかし、Jakujeコメントで述べたように、シェルに配列(ksh、bash、またはzsh)がある場合は、配列を使用することをお勧めします。


完全を期すために:

  • eval任意のコマンドを実行します。したがって、等号の右側にあるコマンドに展開される変数がある場合、そのコマンドが実行されます。次のコード:

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

    と同等a=helloです。

  • declare変数を割り当てるための組み込みbashであり、コマンドを実行しません。次のコード:

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

    と同等a='$(echo hello)'です。

  • letdeclareコマンドを実行しないという点で、に似ています。しかしdeclare、とletは逆に、算術演算に使用できます。

    let a="1 + 2"

    と同等a=3です。


でもABC = 123無効です。equal(=)記号の前後にスペースが追加されているためです。
Mahendran Sakkarai

3

bash FAQには間接参照に関するエントリがあります。ほとんどのユースケースでは、実際に行うべきことは、連想配列またはインデックス付き配列を使用することです。あなたも使うことができます

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
}

面倒なeval引用を避けながら、これを行うためのその他のオプションについては、そのFAQエントリを参照してください。


0

次のようなコードを使用できます。"$x"1=1有効な変数割り当てではないため、コードシェルではコマンドとして実行されます。

LIST="A B C"
for x in $LIST
do
    a=$(echo "$x"1)
    let $a=1
done

どのシェルを使用していますか?bosh bash 4.1.7と4.3.11を使用command not found <varname>=1しようとすると、エラーが発生します(明らかに<varname>はに保存した値ですa
Eric Renouf

@Andrea Corbelliniで説明したように、我々は、聞かせて割り当てた値に宣言やeval使用する必要があります。..
AVJ

1
echoここには必要ありません!ただa="$x"1。またlet、算術コンテキストであるため、数値のみを割り当てることができます。
Peter Cordes 2015

declare $a=foobar動作します。
Peter Cordes 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.