我需要在hudson中运行一个shell脚本.该脚本需要用户的回答.为了给出自动答案,我执行了以下命令行:
yes | ./MyScript.sh
这在Ubuntu终端中运行良好.但是当我在Hudson作业中使用相同的命令时,脚本将自动化并完成所有必需的工作,但最后,我得到以下两行错误:
yes: standard output: Broken pipe yes: write error
这导致我的哈德森工作失败.
我应该如何更改命令行才能在Hudson中正常工作?
但是你怎么解释我在本地运行脚本时没有得到这个错误,但是从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
可能会引发每个写入错误的异常,因此对于java程序来说,在SIGPIPE上不死也不是问题.
像哈德森过程这样的守护进程通常忽略SIGPIPE信号.您不希望您的守护程序死亡只是因为您正在与之通信的进程死亡而且您无论如何都会检查写入错误.
编写为在终端中运行的普通程序不会检查每个printf()
错误的状态,但是如果程序在管道中死亡,你希望它们死掉,例如,如果你运行source | sink
管道; 通常你希望source
进程在退出时尽快sink
退出.
EPIPE
如果SIGPIPE
信号被禁用(因为它看起来像在哈德森的情况下)或者如果程序在接收时没有死亡(yes
程序没有定义任何处理程序,SIGPIPE
因此它应该在接收信号时死亡),则返回写入错误.
我不想忽略错误,我想做正确的命令或修复以摆脱错误.
yes
如果它被杀死或遇到写入错误,进程就会停止的唯一方法.如果将SIGPIPE
信号设置为忽略(由父级),并且没有其他信号终止进程,则yes
在./MyScript.sh
退出时接收写入错误.如果您使用yes
程序,则没有其他选项.
SIGPIPE
信号和EPIPE
错误传达完全相同的信息 - 管道坏了.如果SIGPIPE
启用了yes
进程,那么您将看不到错误.只因为你看到它; 什么都不会发生.它只是意味着./MyScript.sh
退出(成功或失败 - 无关紧要).