変数に格納されているコマンドを呼び出す正しい方法は何ですか?
1と2の間に違いはありますか?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
変数に格納されているコマンドを呼び出す正しい方法は何ですか?
1と2の間に違いはありますか?
#!/bin/sh
cmd="ls -la $APPROOTDIR | grep exception"
#1
$cmd
#2
eval "$cmd"
回答:
Unixシェルは、入力の各行で一連の変換を実行してから実行します。ほとんどのシェルでは、次のようになります(bash
マンページから取得)。
を$cmd
直接使用すると、パラメーター拡張フェーズでコマンドに置き換えられ、その後、次のすべての変換が行われます。
を使用eval "$cmd"
すると、引用符の削除フェーズまで何も実行されません。このフェーズ$cmd
はそのまま返され、パラメータとしてに渡されますeval
。この関数は、実行前にチェーン全体を再度実行することです。
したがって、基本的にはほとんどの場合同じであり、コマンドがパラメーター展開までの変換ステップを使用する場合は異なります。たとえば、ブレース拡張を使用します。
$ cmd="echo foo{bar,baz}"
$ $cmd
foo{bar,baz}
$ eval "$cmd"
foobar foobaz
eval "$cmd"
書かずに行う方法はeval
?$($cmd)
?${$cmd}
?
eval
操作はデータを構文として解析します。したがって、セキュリティに非常に敏感であり、暗黙的に実行することは非常に悪い形式になります。
(インタラクティブに、スクリプトで)実行するeval $cmd
ときに実行cmd="ls -l"
すると、目的の結果が得られます。あなたの場合、パターンのないgrepを持つパイプがあるので、grepパーツはエラーメッセージで失敗します。$cmd
「コマンドが見つかりません」(またはそのような)メッセージを生成するだけです。したがって、エラーメッセージを生成するコマンドではなく、evalを使用して終了したコマンドを使用してみてください。
私はあなたが置くべきだと思います
`
(バッククォート)変数の周りの記号。