通过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() 读取循环中执行此操作,只要您有一些行就读取行,并在没有行的情况下进行后备。 . 如果这听起来合理,我可以帮你写点东西(希望它少于五行!)【参考方案5】:

也许您可以使用命名管道?这是一个例子:

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管道输出但保留退出状态[重复]的主要内容,如果未能解决你的问题,请参考以下文章

匹配时如何退出 Sed [重复]

管道命令输出到 tee 但也保存命令的退出代码 [重复]

Python错误:subprocess.CalledProcessError:命令返回非零退出状态1 [重复]

shell中sed命令的用法

sed 通过换行符替换字符串,但不是相反[重复]

通过管道将 CMD 输出传递给 Powershell [重复]