7

所以,命令:

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

当直接从 shell 执行时,工作正常,输出:

[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.

如果要替换bashecho,您会看到它$5被空字符串替换:

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

因此,当 bash 评估命令时,awk 将打印整行,而不是第五个字段。

当您转义美元符号时(通过使用反斜杠预先添加),变量$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

$1shell 和 awk 在, $2, ...的使用和解释上存在冲突

在所有 Bourne 后代(ash、bash、dash、ksh93、zsh)中,这些表示在命令行上传递的编号参数,而$0替换为当前正在运行的脚本的名称或交互式 shell 的名称。

awk, $1, , ... 中指的是当前记录$2的对应字段,即当前输入行的第一个、第二个等字。 总是指整个记录,包括任何字段分隔符。$0

从 shell(脚本)调用awk时,您必须确保正确引用了 awk 脚本。为防止 shell 插值,请将 awk 代码括在单引号内。

于 2012-08-23T18:43:01.013 回答