bash / sh -c不能使用多个管道

时间:2012-08-23 12:12:38

标签: linux bash shell

所以,命令:

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

这清楚地表明最后一个管道尚未执行。

我做错了什么?

2 个答案:

答案 0 :(得分:14)

您的$5过早得到评估。将其更改为\$5

如果您要将bash替换为echo,您会看到$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}'

答案 1 :(得分:0)

shell和awk在$1$2,... {/ p>的使用和解释方面存在冲突

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

awk$1$2,...中,请参阅当前记录的相应字段,即当前输入行的第一个,第二个等字。 $0始终引用整个记录,包括任何字段分隔符。

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