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

tr3*_*sta 15 pipe

wc -l | test -eq 1
Run Code Online (Sandbox Code Playgroud)

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

Oli*_*Oli 13

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

test $(ls -l | wc -l) -eq 1 && echo "worked"
Run Code Online (Sandbox Code Playgroud)

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

ls -l | wc -l | { read wc; test $wc -eq 7 && echo "woohoo"; }
Run Code Online (Sandbox Code Playgroud)


Joh*_*Doe 8

最简单的方法可能是使用xargs

wc -l | xargs -I % test % -eq 1
Run Code Online (Sandbox Code Playgroud)

  • 或者只是... `wc -l | xargs test 1 -eq` 也有效。 (2认同)

小智 5

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

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

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

dmesg | grep -iw 'nnse' | wc -l
Run Code Online (Sandbox Code Playgroud)

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

echo ${PIPESTATUS[@]}
0 1 0
Run Code Online (Sandbox Code Playgroud)

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

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

如果您想查看管道中特定命令的退出代码是什么,您可以访问该值。grep 命令是上面管道中的第二个命令,但是由于数组从 0 开始,我们需要第一项。

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

echo ${PIPESTATUS[1]}
1
Run Code Online (Sandbox Code Playgroud)

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

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

dmesg | grep -iw 'nnse' | wc -l
[ ${PIPESTATUS[1]} -eq 1 ] && do_something_here
Run Code Online (Sandbox Code Playgroud)

这只是一个片段,因为我不知道您想要什么样的脚本,但我希望了解 PIPESTATUS 可能对您有所帮助。有很多像 PIPESTATUS 这样的 Bash 数组变量非常有用;请参阅Bash 参考指南以了解整个列表,以及其他 Stackexchange 站点以了解其用法示例。