Bash は変数の割り当てをコマンドとして解釈します。

Bash は変数の割り当てをコマンドとして解釈します。

過去数日間何かを試してみましたが、詰まっていました。問題をどのように解決しても、同じ問題が引き続き発生します。 2つの列を持つテキストファイルがあります。最初は変数名、2 番目は実行するコマンド、出力は最初の列の変数に割り当てられます。私は通常、read2つの列を独自の変数に割り当ててから、式全体を新しい変数に入れて実行します。私が何をしても、常にコマンド名で式が表示され、「コマンドが見つかりません」というエラーが発生します。

少し複雑なのでお知らせします。スクリプトは次のとおりです。

while read varName varCmd
do
        echo varName is $varName
        echo varCmd is $varCmd
        declare cmd=$varName=$varCmd
        echo Command is $cmd
        "$cmd"
        echo 1st Value is $varFoo
        echo 2nd Value is $varBar

done < testvars.txt

テキストファイルは次のとおりです。

varFoo  echo foo
varBar  echo bar

割り当て実行自体を除いて、すべてがうまく機能します。これが私が得るものです:

varName is varFoo
varCmd is echo foo
Command is varFoo=echo foo
./testvars.sh: line 8: varFoo=echo foo: command not found
1st Value is
2nd Value is
varName is varBar
varCmd is echo bar
Command is varBar=echo bar
./testvars.sh: line 8: varBar=echo bar: command not found
1st Value is
2nd Value is

=Bashはすべてを演算子ではなくコマンド名(文字列)として解釈するようです。

Bashが割り当て式を正しく解釈するにはどうすればよいですか?

答え1

これはこれを行うことができない方法と似ています。

name=foo
"$name"=123

またはこれ:

cmd="ls -l | grep ^d"
$cmd

割り当て語は、次のように識別される。今後変数を拡張する前に他の演算子を解決する方法と同様に、変数が拡張されます(その後は認識されません)。これは他のシェルが実行するものであり、標準で言うことなので、多くの意味で「正しい」動作です。

他の変数内で名前付き変数を参照するには、namerefs(Bash 4.3以降)を使用でき、declareコマンド自体もこれを実行できます。これは123次の変数に割り当てられますfoo

declare -n p=foo
p=123

または

varname=foo
declare "$varname=123"

しかし、一般的に使用する方が合理的です。連想配列:

key=foo
value=123
declare -A aa
aa["$key"]="$value"

コマンドを保存するには、次を参照してください。

答え2

はい、evalを使用してください。ただし、コマンド文字列を実行する必要があります。

eval $varName=$($varCmd)

それともできます...

declare cmd="$varName=$($varCmd)"
eval $cmd

答え3

evalで説明されているように使用しますman bash

 eval $varBar

関連情報