加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

发布时间:2020-12-15 16:59:27 所属栏目:安全 来源:网络整理
导读:我在检查多管道命令链中的某个命令是否确实抛出错误时遇到问题.通常这不难检查,但是在我的情况下既不设置-o pipefail也不检查${PIPESTATUS [@]}.设置如下: cmd="$snmpcmd $snmpargs $agent $oid | grep grepoptions for_stuff | cut -d',' f$fields | sed '
我在检查多管道命令链中的某个命令是否确实抛出错误时遇到问题.通常这不难检查,但是在我的情况下既不设置-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会抛出一个无效选项 – < grepoption>因为< grepoption>而没有任何意义的错误显然不是$snmpcmd选项.在这个阶段我认为这是一个$snmpcmd的错误,但这是另一个节目……

如果发生错误,procdata将为空.但是,由于两个不同的原因,它可能是空的:要么因为执行$snmpcmd时发生错误(例如超时),要么因为grep找不到它要查找的内容.问题是,我需要能够区分这两种情况并单独处理它们.

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

我知道我可以将错误的流绑定到stdout但是我必须使用启发式方法来检查procdata中的元素是有效还是错误消息,并且我冒着获得误报的风险.我还可以将stdout传递给/ dev / null并仅捕获错误流并检查是否${#procdata [@]} -eq 0.但是我必须重复调用以获取实际数据并且整个命令是时间成本高(约3-5s).我不想两次打电话.或者我可以使用临时文件来写错误,但我宁愿这样做也没有创建/删除文件的开销.

有什么想法我怎么能用bash做这个工作?

谢谢

P.S:

$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"

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读