如何在测试程序中使用管道中的值?


10
wc -l | test -eq 1

这行不通。我想将wc的结果与1的值进行比较。我该怎么做?

Answers:


9

它不能回答有关管道的问题,但是您可以重新排列:

test $(ls -l | wc -l) -eq 1 && echo "worked"

SO有一些解决方案,这是最好的:

ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }

4

如果您正在使用Bash,则可能要研究PIPESTATUS变量。如Bash参考指南中所述,PIPESTATUS是

一个数组变量(请参阅Arrays),其中包含最近执行的前台管道(可能仅包含一个命令)中进程的退出状态值的列表。

我们可以使用PIPESTATUS找出此管道的退出代码:

dmesg | grep -iw 'nnse' | wc -l

如果现在查询数组变量,您将获得引用管道中使用的命令的退出状态:

echo ${PIPESTATUS[@]}
0 1 0

(在索引数组中,上面的那些退出代码在数组中由0 1和2表示,因为数组在Bash中始终从0开始。)

在这里,我们看到第二个命令返回1,其余命令返回0;但是,wc -l如果匹配项为零,则返回0,这不是错误。失败用一个非零值表示,还有其他错误值,例如127(找不到命令),还有更多特定于相关程序的代码。

如果要查看管道中特定命令的退出代码是什么,则可以访问该值。grep命令是上面管道中的第二个命令,但是随着数组从0开始,我们需要输入1。

因此,要找出grep命令的退出代码,请再次运行上述管道(因为如果您已经运行echo ${PIPESTATUS[@]},则PIPESTATUS的内容将被用完),然后执行以下命令,该命令将返回1(退出代码):

echo ${PIPESTATUS[1]}
1

在脚本中,在查找PIPESTATUS数组变量的内容之前,请确保管道已完成执行。

有关有趣地使用PIPESTATUS数组变量的示例,请参见有关结合Bash命令分组和管道状态的答案。您可以按照Gilles在注释中建议的方式测试数组变量,尽管您首先需要再次运行管道:

dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here

这只是一个片段,我不知道您打算使用哪种脚本,但我希望了解PIPESTATUS可能对您有用。有很多Bash数组变量,例如PIPESTATUS可能非常有用。有关整个列表,请参见Bash参考指南;有关其用法的示例,请参见其他Stackexchange网站。



1

这并不涵盖所有test情况,但如果你可以使用正则表达式,而grep该管道线,这是很简单的,因为greptest在它有一个非零退出状时,没有找到匹配

cat file | wc -l | grep -qE '^\s*1\s*$'

扩展的正则表达式使您可以使用此技术来处理许多情况。对于傻笑,一个测试用例:

for i in 1 11 '' foo; do 
  if echo $i | grep -qE '^\s*1\s*$'; then 
    echo "'$i' matched"
  else
    echo "'$i' didn't match."
  fi
done

输出:

'1' matched
'11' didn't match.
'' didn't match.
'foo' didn't match.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.