4

私は現在、いくつかの異なるディストリビューション (主に Redhat および Debian ベース) で一連のパッケージをインストール/チェックする大規模な BASH スクリプトを変更している最中です。

ディストリビューション間のいくつかの違い (例: rpm と dpkg、yum と apt など) を処理するために、スクリプトがif debian then this, otherwise thisステートメントでいっぱいにならないように、いくつかの変数にさまざまなコマンド文字列をロードしようとしています。ただしawk、 eval ステートメント内に配置されるのが気に入らないようで、その理由がわかりません。

# Example dpkg --list output
# ii  bash       4.1-2ubuntu3    The GNU Bourne Again SHell

dpkg --list | grep 'bash'
# Outputs bash entries in dpkg.

cmd="dpkg --list | grep 'bash'"
eval $cmd                                       
# Outputs as expected, same as above.

dpkg --list | awk '/^.i/ { print $2 }'
# Outputs as expected, a list of package names.

cmd="dpkg --list | awk '/^.i/ { print $2 }'"
eval $cmd
# Awk prints full output from dpkg for every line matching the regex.

上記のコードでは、特定のパッケージを grep するだけで問題なく動作し、期待どおりに出力されますが、awk を使用してパッケージ名の完全なリストを生成しようとすると、print $2無視されているように見え、単に行全体が出力されます。

何か案は?

4

3 に答える 3

7

これがまさにその理由だ:

cmd="dpkg --list | awk '/^.i/ { print $2 }'"
echo $cmd

Output:
dpkg --list | awk '/^.i/ { print }'

$ 記号をエスケープします。

cmd="dpkg --list | awk '/^.i/ { print \$2 }'"
于 2012-07-12T09:58:38.403 に答える
0

eval は $2 を評価し、これを試してその値に置き換えます ($ 文字をエスケープします)。

cmd="dpkg --list | awk '/^.i/ { print \$2 }'"
于 2012-07-12T09:57:56.667 に答える
0

これが必要です(awkスクリプトで$をエスケープする必要があります):

cmd="dpkg --list | awk '/^.i.+bash/{ print \$2 }'"
eval $cmd

それでも、この場合に使用する理由がわかりません。evalここでいくつかの問題が発生します (そのうちの 1 つは、明らかに/^.i.*bash/正規表現を使用できず (シェルがグロブを展開するか、\正規表現内で渡す)、 に解決する必要があること/^.i.+bash/です。

于 2012-07-12T10:09:19.133 に答える