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

如何在测试程序中使用来自管道的值?
wc -l | test -eq 1

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

答案1

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

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

还有SO 上的一些解决方案,这是最棒的:

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

答案2

最简单的方法可能是使用参数

wc -l | xargs -I % test % -eq 1

答案3

如果你正在使用 Bash,你可能需要研究 PIPESTATUS 变量。如Bash 参考指南,PIPESTATUS 是

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

我们可以使用 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 开始,因此我们需要第一个条目。

因此,要找出 grep 命令的退出代码,请再次运行上述管道(因为如果您已经运行,PIPESTATUS 的内容将已经被用尽echo ${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 站点以获取其用法的示例。

答案4

这并不涵盖所有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.

相关内容