我正在Jenkins(Jenkins是一个开源的持续集成工具)中执行一个shell命令列表。 其中一个命令是运行一个Java程序,它执行一些数据validation。 如果遇到无效date,Java程序将以非零退出代码退出,这样jenkins可以发现这次构build失败。
不幸的是,Java程序打印太多的日志到标准输出和标准错误,只有less数是有用的。 由于Java程序无法修改,我决定用grep过滤输出。 所以我写了这个shell:
java -cp $CLASSPATH MetaValidatorMain | grep -v "useless keyword1"| grep -v "useless keyword2"
但问题是,在执行shell之后,父进程(Jenkins)得到了java的grep indead的退出代码,因此Jenkins无法确定构build是否成功。
我也试过这个:
(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
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
很长一段时间,但是你可以将程序输出重定向到一个文件,捕获返回,然后grep你想要的内容的输出文件:
java -cp $CLASSPATH MetaValidatorMain > /tmp/outfile.txt 2>&1 RETURN_CODE=$? grep -v "useless keyword1" /tmp/outfile | grep -v "useless keyword2" exit RETURN_CODE