86

変数に格納されたコマンドを呼び出す正しい方法は何ですか?

1と2の違いはありますか?

#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"

#1
$cmd

#2
eval "$cmd"
4

4 に答える 4

99

Unixシェルは、入力の各行で一連の変換を実行してから実行します。ほとんどのシェルでは、次のようになります(Bashのmanページから取得)。

  • 最初の単語分割
  • ブレース拡張
  • チルダ拡張
  • パラメータ、変数、および算術展開
  • コマンド置換
  • 二次単語分割
  • パス拡張(別名グロブ)
  • 見積もりの​​削除

直接使用$cmdすると、パラメーター拡張フェーズ中にコマンドに置き換えられ、その後、以降のすべての変換が行われます。

を使用eval "$cmd"すると、引用符の削除フェーズまで何も実行されません。ここで、$cmdはそのまま返され、パラメータとしてに渡されますeval。この関数は、実行する前にチェーン全体を再度実行します。

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

$ cmd="echo foo{bar,baz}"

$ $cmd
foo{bar,baz}

$ eval "$cmd"
foobar foobaz
于 2011-01-12T12:29:59.580 に答える
6

eval $cmd私たちが行ったときにcmd="ls -l"(インタラクティブにスクリプトで)行うだけで、目的の結果が得られます。あなたの場合、パターンのないgrepを持つパイプがあるため、grep部分はエラーメッセージで失敗します。「コマンドが見つかり$cmdません」(またはそのような)メッセージが生成されます。

したがって、使用してeval ( 「The args are read and concatenated together」の近く)を試し、エラー メッセージを生成するコマンドではなく、完成したコマンドを使用してください。

于 2011-01-12T12:25:15.337 に答える
-4

入れるべきだと思います

`

変数を (バックティック) 記号で囲みます。

于 2011-01-12T12:15:46.113 に答える