通过sed输出管道但保留退出状态

时间:2011-02-11 11:45:15

标签: shell maven-2 sed

我通过sed管道长时间运行的构建过程的输出,用于语法高亮,实现为“mvn”的包装。

此外,我还有一个“监视器”脚本,可在构建完成时通知桌面。监视器脚本检查其参数的退出状态并报告“成功”或“失败”。

通过sed管道maven输出,即使构建失败,退出状态也总是“ok”。

如何通过sed管道正确的退出状态?

有替代方案吗?

6 个答案:

答案 0 :(得分:2)

也许PIPESTATUS变量可以提供帮助。

答案 1 :(得分:1)

这是众所周知的后方疼痛。如果您正在使用bash(可能还有许多其他现代sh变体),您可以访问PIPESTATUS数组以获取管道中较早的程序的返回值。 (通常,管道的返回值是管道中最后一个程序的返回值。)如果您使用的是没有PIPESTATUS的shell(或者如果您想要可移植性),则可以执行以下操作:< / p>

#!/bin/sh

# run 'echo foo | false | sed s/f/t/', recording the status
# of false in RV
eval $( { { echo foo | false; printf RV=$? >&4; } |
     sed s/f/t/ >&3; } 4>&1; ) 3>&1
echo RV=$RV

# run 'echo foo | cat | sed s/f/t/', recording the status
# of cat in RV
eval $( { { echo foo | cat; printf RV=$? >&4; } |
     sed s/f/t/ >&3; } 4>&1; ) 3>&1
echo RV=$RV


在每种情况下,RV将分别包含false和cat的返回值。

答案 2 :(得分:1)

如果您正在使用Bash,则可以选择使用set -o pipefail选项,但由于它依赖于bash,因此它不可移植,并且无法使用crontab,除非您将整个包裹起来在bash环境中的事情(糟糕的解决方案)。

http://bclary.com/blog/2006/07/20/pipefail-testing-pipeline-exit-codes/

答案 3 :(得分:0)

Bastil,因为管道不关心退出状态,你只能知道sed是否合理退出。如果没有找到预期的文本,我会增强sed脚本(或者可能考虑使用3-line 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单行中)

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

一周后,我得到了一个解决方案:

最初我想做

monitor "mvn blah | sed -e SomeHighlightRegEx"

监视器会对sed的退出状态(而不是mvn)作出反应。

更容易做到

monitor "mvn blah" | sed -e SomeHiglightRegEx

请注意,这会通过sed管理monitor的输出,而monitor脚本会对mvn的状态作出反应。

非常感谢其他想法。