7

したがって、コマンド:

dmesg | grep 'Attached SCSI disk' | awk '{ print $5}'

シェルから直接実行すると、正常に動作し、次のように出力されます。

[sdb]
[sdc]
[sda]

しかし、私がそれを起動するとき:

sh -c "dmesg | grep 'Attached SCSI disk' | awk '{ print $5}'"
# or
bash -c "dmesg | grep 'Attached SCSI disk' | awk '{ print $5}'"

私は得る:

[ 2.460353] sd 1:0:0:0: [sdb] Attached SCSI disk
[ 2.461348] sd 2:0:0:0: [sdc] Attached SCSI disk
[ 2.464181] sd 0:0:0:0: [sda] Attached SCSI disk

これは、最後のパイプが実行されていないことを明確に示しています。

私は何が間違っているのですか?

4

2 に答える 2

16

評価$5が早すぎます。に変更し\$5ます。

に置き換える場合は、空の文字列に置き換えられているbashことechoがわかります。$5

 % echo "dmesg | grep 'Attached SCSI disk' | awk '{ print $5}'"
 dmesg | grep 'Attached SCSI disk' | awk '{ print }'

したがって、bashがコマンドを評価するとき、awkは5番目のフィールドではなく、行全体を出力します。

ドル記号をエスケープすると(バックスラッシュを前に付けることにより)、変数$5は保持されます。

% echo "dmesg | grep 'Attached SCSI disk' | awk '{ print \$5}'"
dmesg | grep 'Attached SCSI disk' | awk '{ print $5}'
于 2012-08-23T12:16:03.830 に答える
1

シェルとawkの使用と解釈には、、、..の競合があり$1ます$2

すべてのボーンの子孫(ash、bash、dash、ksh93、zsh)で、これらはコマンドラインで渡された番号付きの引数を示し、$0現在実行中のスクリプトの名前またはインタラクティブシェルの名前に置き換えられます。

、、、 ...はawk、現在のレコードの対応するフィールド、つまり、現在の入力行の最初、2番目などの単語を参照します。 フィールドセパレータを含むレコード全体を常に参照します。$1$2$0

シェル(スクリプト)から呼び出すときawkは、awkスクリプトが適切に引用されていることを確認する必要があります。シェルの補間を防ぐには、awkコードを一重引用符で囲みます。

于 2012-08-23T18:43:01.013 に答える