2011-01-12 11 views

答えて

67

UNIXシェルは、実行する前に入力の各行で一連の変換を実行します。

  • 初期単語の分割
  • ブレース展開
  • チルダ展開
  • パラメータ、変数および算術展開
  • コマンド:ほとんどのシェルにとっては、(bash manページから引用)このようになります置換
  • 2次単語分割
  • パスe $cmdを使用してxpansion(別名グロブ)
  • クォート除去

は直接、それはパラメータ展開の段階であなたのコマンドに置き換え取得し、それは、すべての次の変換を受けます。 eval "$cmd"を使用して

$cmdがあるとして返され、その機能が実行される前に再びチェーン全体を実行することですevalにパラメータとして渡された引用除去相、までは何もしません。

基本的には、ほとんどの場合同じですが、コマンドがパラメータ拡張までの変換ステップを使用する場合は異なります。たとえば、中括弧拡張を使用します。

$ cmd="echo foo{bar,baz}" 
$ $cmd 
foo{bar,baz} 
$ eval "$cmd" 
foobar foobaz 
+5

'eval'を書かずに' eval '$ cmdを実行するには? '$($ cmd)'? '$ {$ cmd}'? –

+2

@StevenLuこれらのどれも同等ではありません - '演算は構文としてデータを解析するため、セキュリティに非常に敏感であり、暗黙的に行うことは非常に悪い形式になります。 –

-2

私は湯はあなただけ行う場合は、あなたの変数(Shiftキーが押された場合は〜と1)

+3

これはコマンドの出力を実行します。 ls -lの場合は "total"コマンドが見つかりません "というメッセージが生成されます(合計はls -lの出力の一部なので)これはあなたが望むものではありません –

3

周り `記号を置くと思いますeval $cmd 我々はやるときcmd="ls -l"(対話形式で、スクリプトで)我々が得ます所望の結果。あなたのケースでは、パターンのないgrepを持つパイプがあるので、grepパーツはエラーメッセージで失敗します。 $cmdは「コマンドが見つかりません」(または何らかの)メッセージを生成します。 したがって、エラーメッセージを生成するコマンドではなく、evalを使用して終了したコマンドを使用してみてください。

+0

それは誤った"grep exception"でなければなりません –

+0

それはおそらく動かないでしょう(私のテストではbashとzshの下ではなかったので)$ cmdだけではなくevalを使用します。 –

関連する問題