2番目の行は "a = b"を生成し、それをメインシェルのコンテキストで実行すると、値b
の新しい変数a
が生成されます。 しかし、私が実際に手に入れたのは、2行目以降のエラーメッセージです。bash: a=b: command not found
なぜこのbashコードは機能しませんか?
なぜそうですか?
2番目の行は "a = b"を生成し、それをメインシェルのコンテキストで実行すると、値b
の新しい変数a
が生成されます。 しかし、私が実際に手に入れたのは、2行目以降のエラーメッセージです。bash: a=b: command not found
なぜこのbashコードは機能しませんか?
なぜそうですか?
これは、bashがコマンドラインを解析する順序が原因です。変数の変更やコマンド置換(例:バッククックのコマンド)を行う前に、変数定義(例えば、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
へのすべての参照を二重引用符で囲みます。これは、bashが通常の解析プロセスを完了してからeval
コマンドを認識するため、が2回のbash解析(ワード分割など)の後の段階を防ぐためです。解析プロセス全体をやり直してくださいをもう一度やり直してください。 eval
を使用して予期せぬ結果を得るのは本当に簡単です。これにより、少なくともいくつかの問題の可能性が排除されます。
あなたは面白いアポストロフィで$x
を試しましたか? echo
がなければ、エコーはコマンドを実行するのではなく、文字列を表示するだけのようです。
これらはバッククォートと呼ばれます(そして '$ x'と' echo $ x'はどちらも同じ結果を生成します)。 – Amber
ああ、知っておいてよかったよ! – IProblemFactory
てみ
eval $x
(そして、この回答が掲載されるために、我々は30個の文字を必要とする)
あなたの最初のエコーラインは、サブシェルで実行され、呼び出し先にその値を返しているん何..同じ結果が$()
を使用して達成されています - ところで - バックティックよりも使いやすいです。
だから、まずecho $x
(これはa=b
を返します)を実行しています。そして、バックティックのために、a=b
がその行をコマンドとして実行しようとするシェルに返されます。これは明らかに動作しません。
はシェルでこれを試してみてください:
$(echo ls)
そして、あなたは明らかに何が起こっているかが表示されます。
これは私に関連する問題を助けました...私はバッククッキーを使ってシェルスクリプトを実行していて、スクリプトはエコー "ハイ"を行いました。私は呼び出し先の変数にstdoutをキャプチャしなかったので、呼び出し先は./hiと./hiが実行されないようにしようとしました... – nterry
説明をありがとう! –