通过sed管道输出但保留退出状态[重复]
Posted
技术标签:
【中文标题】通过sed管道输出但保留退出状态[重复]【英文标题】:piping output through sed but retain exit status [duplicate] 【发布时间】:2011-06-25 12:19:15 【问题描述】:我通过 sed 管道输出一个长期运行的构建过程的输出以进行语法高亮,实现为“mvn”的包装器。
此外,我还有一个“监控”脚本,当构建完成时,它会在桌面上通知我。监控脚本检查其参数的退出状态并报告“成功”或“失败”。
通过 sed 管道化 maven 输出,退出状态始终为“ok”,即使构建失败。
我怎样才能通过 sed 传递正确的退出状态?
还有其他选择吗?
【问题讨论】:
【参考方案1】:也许PIPESTATUS 变量可以提供帮助。
【讨论】:
我就是这样做的:bash -e 'mvn blah | sed -e SomeHighlightRegEx; exit $PIPESTATUS[0]'
【参考方案2】:
如果您使用的是 Bash,则可以选择使用 set -o pipefail
选项,但由于它依赖于 bash,因此它不可移植,并且无法在 crontab
上工作,除非您将整个内容包装在 bash 中env(不好的解决方案)。
http://bclary.com/blog/2006/07/20/pipefail-testing-pipeline-exit-codes/
【讨论】:
【参考方案3】:这是众所周知的背部疼痛。如果您正在使用 bash(可能还有许多其他现代 sh 变体),您可以访问 PIPESTATUS 数组以获取管道中较早的程序的返回值。 (通常,管道的返回值是管道中最后一个程序的返回值。)如果您使用的外壳没有 PIPESTATUS(或者如果您想要可移植性),您可以执行以下操作: #!/bin/sh # 运行 'echo foo |假 | sed s/f/t/',记录状态 # RV 中的错误数 eval $( echo foo | false; printf RV=$? >&4; | sed s/f/t/ >&3; 4>&1; ) 3>&1 回声 RV=$RV # 运行 'echo foo |猫 | sed s/f/t/',记录状态 # 房车里的猫 eval $( echo foo | cat; printf RV=$? >&4; | sed s/f/t/ >&3; 4>&1; ) 3>&1 回声 RV=$RV
在每种情况下,RV 将分别包含 false 和 cat 的返回值。
【讨论】:
【参考方案4】:Bastil,因为管道不关心退出状态,你只能知道 sed 是否正常退出。如果找不到预期的文本,我会增强 sed 脚本(或者可能考虑使用 3 行 Perl 脚本)以失败状态退出,类似于伪代码:
read($stdin)
if blank
exit(1) // output was blank, or on $stderr
else
regular expression substitution here
end
// natural exit success here
您可以将其作为 perl 单行器来完成,同样可以在 sedscript 中完成(但据我所知,在 sed 单行器中不行)
【讨论】:
但这只会在生成整个输出而不是以流式“sed”方式进行正则表达式替换,对吗?我的 PERL 知识已被弃用... 完全有可能,您也可以在 perl 中的 while(也许您可以使用命名管道?这是一个例子:
FIFODIR=`mktemp -d`
FIFO=$FIFODIR/fifo
mkfifo $FIFO
cat $FIFO & # An arbitrary pipeline
if false > $FIFO
then
echo "Build succeeded"
else
echo "Build failed" # This line WILL execute
fi
rm -r $FIFODIR
【讨论】:
【参考方案6】:一周后我得到了解决方案:
本来我想做的
monitor "mvn blah | sed -e SomeHighlightRegEx"
monitor 会对 sed(而不是 mvn)的退出状态做出反应。
这样做更容易
monitor "mvn blah" | sed -e SomeHiglightRegEx
请注意,这将通过 sed 管道输出监视器,而监视器脚本对 mvn 的状态作出反应。
无论如何感谢其他想法。
【讨论】:
以上是关于通过sed管道输出但保留退出状态[重复]的主要内容,如果未能解决你的问题,请参考以下文章