+-
java-在Linux Shell中同时过滤输出并获取程序的退出代码
我正在通过执行一系列 Shell命令在Jenkins(Jenkins是一个开源持续集成工具)中运行一项工作.命令之一是运行 Java程序,该程序执行一些数据验证.如果遇到无效日期,则Java程序将以非零退出代码退出,因此Jenkins可以发现这次构建失败.

不幸的是,Java程序将太多日志输出到stdout和stderr,只有其中一些有用.由于无法修改Java程序,因此我决定使用grep过滤输出.所以我把shell写成:

java -cp $CLASSPATH MetaValidatorMain | grep -v "useless keyword1"| grep -v "useless keyword2"

但是问题在于,在执行完这些行之后,父进程(Jenkins)获得了Java的grep indead的退出代码,因此Jenkins无法确定构建是否成功.

我也试过这个:

(java -cp $CLASSPATH MetaValidatorMain || exit 1) | grep -v "useless keyword1"| grep -v "useless keyword2"

也没有用.

谁能告诉我如何编写shell行来过滤输出并同时获得正确的退出代码.

谢谢

最佳答案
有3种方法可以做到这一点.但是,您当前的设置应该可以工作.原因是如果命令失败,grep将不匹配任何内容,因此grep将返回状态1(除非程序始终显示该文本,无论如何).

管道失败

第一种方法是设置pipefail选项.这是最简单的方法,它的基本作用是设置退出状态$?返回最后一个程序的退出代码以退出非零值(如果成功退出,则返回零).

# false | true; echo $?
0
# set -o pipefail
# false | true; echo $?
1

$PIPESTATUS

Bash还有一个名为$PIPESTATUS的变量,它包含最后一个命令中所有程序的退出状态.

# true | true; echo "${PIPESTATUS[@]}"
0 0
# false | true; echo "${PIPESTATUS[@]}"
1 0
# false | true; echo "${PIPESTATUS[0]}"
1
# true | false; echo "${PIPESTATUS[@]}"
0 1

您可以使用第三个命令示例来获取所需管道中的特定值.

但是,此解决方案可能不可用.我认为$PIPESTATUS可能是在bash的较新版本中添加的,并且您的操作系统可能没有.

单独执行

这是解决方案中最笨拙的.分别运行每个命令并捕获状态

# java -cp $CLASSPATH MetaValidatorMain > /tmp/outfile.txt 2>&1
# RETURN_CODE=$?
# grep -v "useless keyword1" /tmp/outfile | grep -v "useless keyword2"
# exit RETURN_CODE
点击查看更多相关文章

转载注明原文:java-在Linux Shell中同时过滤输出并获取程序的退出代码 - 乐贴网