Bash:检查多管道命令链的退出状态

标签 bash pipe snmp exit-code command-substitution

我在检查多管道命令链中的某个命令是否确实抛出错误时遇到问题。通常这不难检查,但也不难 set -o pipefail也不检查 ${PIPESTATUS[@]}适用于我的情况。设置是这样的:

cmd="$snmpcmd $snmpargs $agent $oid | grep <grepoptions> for_stuff | cut -d',' f$fields | sed 's/ubstitute/some_other_stuff/g'"

注意 1:该命令已经过全面测试并且运行良好。

现在,我想将该命令的输出存储在一个名为 procdata 的数组中.因此,我做了:

declare -a procdata
procdata=( $(eval $cmd) )

注2:eval是必要的,否则 $snmpcmd抛出 invalid option -- <grepoption>没有意义的错误,因为 <grepoption>不是 $snmpcmd选项显然。在这个阶段,我认为这是 $snmpcmd 的错误但那是另一个节目......

如果发生错误,procdata将是空的。但是,由于两个不同的原因,它可能为空:或者是因为在执行 $snmpcmd 时发生错误。 (例如超时)或因为 grep找不到它要找的东西。问题是,我需要能够区分这两种情况并分别处理。

因此,set -o pipefail不是一个选项,因为它会传播任何错误,我无法区分管道的哪一部分失败了。另一方面echo ${PIPESTATUS[@]}总是 0procdata=( $(eval $cmd) ) 之后即使我有很多管道!?。然而,如果我直接在提示符下执行整个命令并调用 echo ${PIPESTATUS[@]}紧接着,它会正确返回所有管道的退出状态。

我知道我可以将 err 流绑定(bind)到 stdout,但我必须使用启发式方法来检查 procdata 中的元素是否是有效或错误消息,我冒着误报的风险。我还可以将标准输出通过管道传输到 /dev/null并仅捕获错误流并检查是否${#procdata[@]} -eq 0 .但是我必须重复调用以获取实际数据,并且整个命令非常耗时(大约 3-5 秒)。我不想叫它两次。或者我可以使用一个临时文件来写入错误,但我宁愿在没有创建/删除文件开销的情况下这样做。

关于如何在 bash 中完成这项工作有什么想法吗?

谢谢

附言:

$ echo $BASH_VERSION
4.2.37(1)-release

最佳答案

这里有很多东西:

(1) 当您说 eval $cmd 并尝试获取命令 $cmd 中包含的管道中进程的退出值时,echo "${PIPESTATUS[@]}" 将包含 eval 的退出状态。您需要提供完整的命令行,而不是 eval

(2) 在将管道的输出分配给变量时,您需要获取PIPESTATUS。稍后尝试这样做是行不通的。


举个例子,你可以说:

foo=$(command | grep something | command2; echo "${PIPESTATUS[@]})"

这会将管道的输出和 PIPESTATUS 数组捕获到变量 foo 中。

您可以通过以下方式将命令输出放入数组:

result=($(head -n -1 <<< "$foo"))

PIPESTATUS 数组通过说

tail -1 <<< "$foo"

关于Bash:检查多管道命令链的退出状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20564652/

相关文章:

bash - 如何在 cygwin 中关闭蜂鸣斜杠铃?

bash - 当管道中发生错误时,如何使 bash 脚本最终失败

c - 有人可以帮助我用 c 编写代码吗?

c++ - C/C++ 的 snmp 代理库?

python - 通过 pip [Python] 安装 easysnmp 时出错

linux - 如何在bash函数中将数字显示到小数点后两位

Bash Sed 查找并替换为特殊字符

python - 在Windows上从Bash传递路径到Python会自动尝试将其转换为绝对路径-是否可以禁止该路径?

Angular 2 : FilterPipe : Cannot read property 'filter' of undefined

c++ - 需要一个简单的 SNMP 库 c++