なぜこのバッシュコードが機能しないのですか?
質問
x="a=b"
`echo $x`
echo $a
2番目の行が「a = b」を生成し、メインシェルのコンテキストで実行すると予想され、新しい変数になります a
価値で b
。ただし、私が実際に得るのは(コマンドを手動で入力した場合)2番目の行の後のエラーメッセージです。 bash: a=b: command not found
どうしてこんなことに?
解決
それは、バッシュがコマンドラインを解析する順序のためです。可変定義を探します(例: a=b
) 前 変数とコマンドの置換を実行します(例:バックテックのコマンド)。このため、時代までに echo $x
に置き換えられます a=b
, 、Bashがこれを可変定義と見なすには遅すぎて、代わりにコマンドとして解析されます。あなたがちょうど使用した場合、同じことが起こっていたでしょう $x
コマンドとして(バックティックでエコーの代わりに)。 @MVDSの答えのように、 eval
コマンドを使用して、コマンドを最初から賠償するように強制することができます。つまり、可変定義として認識されることを意味します。
$ 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
ダブルクォートでは、これはバッシュ解析の後期段階(単語分割など)を防ぐためです 2回, 、bashは通常の解析プロセスを終了するため、 eval
コマンド、次に解析プロセス全体をやり直します また. 。使用して予期せぬ結果を得るのは本当に簡単です eval
, 、そしてこれにより、少なくともトラブルの可能性の一部が削除されます。
他のヒント
試す
eval $x
(そして、この答えを投稿するには30文字が必要です)
あなたの最初のエコーラインが行うことは、サブシェルで実行され、その値をカリーに返すことです。同じ結果が使用されています $()
そして、 - ちなみに - バックテックよりも使いやすい。
だから、あなたがしていることは最初に実行されることです echo $x
(戻ります a=b
)。そして、バックティックのために、 a=b
そのラインをコマンドとして実行しようとするシェルに返されます。
これをシェルで試してみてください:
$(echo ls)
そして、あなたは何が起こっているのかをはっきりと見るでしょう。
試しましたか $x
その面白いアポストロフィで?それなし echo
, 、エコーは、コマンドを実行するのではなく、文字列を表示するためだけのようです。