x="a=b"
`echo $x`
echo $a
2行目で「a=b」が生成され、メインシェルのコンテキストで実行されると、a値が新しい変数になりますb。ただし、実際に表示されるのは(コマンドを手動で入力した場合)、2行目以降のエラーメッセージです。bash: a=b: command not found
どうしてこんなことに?
試す
eval $x
(そして、この回答を投稿するには30文字が必要です)
最初のエコーラインはサブシェルで実行され、その値を呼び出し先に返します。同じ結果がを使用して達成$()され、バックティックよりも使いやすくなっています。
したがって、あなたがしていることは最初に実行することですecho $x(これはを返しますa=b)。そして、バッククォートのために、a=bその行をコマンドとして実行しようとするシェルに返されますが、これは明らかに機能しません。
シェルでこれを試してください:
$(echo ls)
そして、あなたは何が起こっているのかをはっきりと見るでしょう。
これは、bashがコマンドラインを解析する順序が原因です。変数とコマンド置換(バックティックのコマンドなど)を実行する前に、変数定義(例a=b)を検索します。このため、がに置き換えられるまでに、bashがこれを変数定義と見なすには遅すぎ、代わりにコマンドとして解析されます。(バックティックのエコーの代わりに)コマンドとして使用した場合も同じことが起こります。@mvdsの回答のように、コマンドを使用して、コマンドを最初から強制的に再解析することができます。つまり、変数定義として認識されます。echo $xa=b$xeval
$ x="a=b"
$ `echo $x`
-bash: a=b: command not found
$ $(echo $x) # Exact same thing, but with cleaner syntax
-bash: a=b: command not found
$ $x # This also does the same thing, but without some extra steps
-bash: a=b: command not found
$ eval "$x" # This will actually work
$ echo $a
b
$ a= # Start over
$ eval "$(echo "$x")" # Another way of doing the same thing, with extra steps
$ echo $a
b
evalを使用する場合は、すべての参照を二$x重引用符で囲んでいることに注意してください。これは、bashが通常の解析プロセスを終了し、コマンドを実行してから、解析プロセス全体をやり直します。を使用すると予期しない結果が得られるのは非常に簡単です。これにより、問題が発生する可能性の少なくとも一部が取り除かれます。evaleval
$xその面白いアポストロフィを試してみましたか?がないechoと、echoは文字列を表示するためだけのものであり、コマンドを実行するためのものではないようです。