【问题标题】:piping output through sed but retain exit status [duplicate]通过sed管道输出但保留退出状态[重复]
【发布时间】:2011-06-25 12:19:15
【问题描述】:

我通过 sed 管道输出一个长期运行的构建过程的输出以进行语法高亮,实现为“mvn”的包装器。

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

通过 sed 管道化 maven 输出,退出状态始终为“ok”,即使构建失败。

我怎样才能通过 sed 传递正确的退出状态?

还有其他选择吗?

【问题讨论】:

    标签: shell maven-2 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 的状态作出反应。

          无论如何感谢其他想法。

          【讨论】:

            猜你喜欢
            • 2021-05-20
            • 2012-02-08
            • 1970-01-01
            • 2010-11-16
            • 1970-01-01
            • 2011-10-15
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多