一尘不染

Hudson:“是:标准输出:断管”

jenkins

我需要在Hudson中运行Shell脚本。该脚本需要用户回答。为了给出自动答案,我做了以下命令行:

yes | ./MyScript.sh

这在Ubuntu终端中运行良好。但是,当我在Hudson作业中使用相同的命令时,脚本将自动执行所需的所有工作,但是最后,我得到了这两行错误:

yes: standard output: Broken pipe
yes: write error

这导致我的哈德森工作失败。

如何更改命令行以在Hudson中正常工作?


阅读 235

收藏
2020-07-25

共1个答案

一尘不染

但是,您如何解释我在 本地 运行脚本时没有收到此错误,而从Hudson作业 远程 运行该脚本却收到错误?

在终端( 本地 )中运行时;yes被已经退出SIGPIPE时试图写入管道的信号杀死MyScript.sh

无论是在Hudson中( 远程
)运行命令,都会捕获该信号(将其处理程序设置为SIG_IGN,您可以通过运行trap命令并在输出中搜索SIGPIPE
对其进行测试),并且不会为新的子进程恢复该信号(yes以及任何运行的MyScript.sh示例(sh根据您的情况)。这会导致写入错误(EPIPE)而不是信号。yes检测到写入错误并报告。

您可以简单地忽略错误消息:

yes 2>/dev/null | ./MyScript.sh

您还可以针对运行管道的组件报告错误。错误是在分叉孩子之后,没有将SIGPIPE恢复到默认处理程序。这是程序在POSIX系统上的终端中运行时所期望的。尽管我不知道对于基于Java的程序是否有标准方法可以做到这一点。jvm可能会为每个写入错误引发一个异常,因此不死于SIGPIPE对Java程序而言不是问题。

哈德逊进程等守护程序通常会忽略SIGPIPE信号。您不希望您的守护程序仅因为与您通信的进程死亡而死亡,无论如何都要检查写入错误。

编写为要在终端上运行的普通程序不会检查每个程序的状态printf()是否有错误,但是您希望它们在流水线下的程序终止时消失,例如,如果您在运行source | sink流水线;通常source,如果sink退出,您希望进程尽快退出。

EPIPE如果SIGPIPE禁用了信号(如在哈德逊的情况下)或程序在接收到它时不死(yes程序未定义任何处理程序,SIGPIPE因此它应在接收到信号时死掉),则返回写错误。

我不想忽略该错误,我想执行正确的命令或修复该错误。

唯一的
办法yes,如果它被杀死或遇到写入错误进程停止。如果将SIGPIPE信号设置为(被父)忽略,并且没有其他信号杀死该进程,则yes./MyScript.sh退出时收到写错误。如果使用yes程序,则没有其他选择。

SIGPIPE 信号和EPIPE错误传达完全相同的信息-
管道损坏
。如果SIGPIPE启用了yes流程,则不会看到该错误。只是因为你看到了;没有新的事情发生。这仅表示./MyScript.sh退出(成功或失败-
无关紧要)。

2020-07-25