我一直在试图弄清楚如何捕获 nohup 命令的退出状态,然后根据状态发送邮件。
下面是我的代码:
if [[ "" != "$PID" ]]; then
echo "killing $PID"
kill -9 $PID
nohup java -jar Xyz-port-0.0.1.jar &
<< Exit Code and then send mail if Exit
code is 0>>
else
echo "Process doesn't exist"
fi
后台作业总是成功启动:
nohup
在命令终止之前,您无法在后台启动您的 Java 程序并检测它是否运行良好。nohup
如果找不到或无法启动java
,或者当 Java 程序终止时,该命令将终止。它不是nohup
在后台运行您的程序。它只是让您的程序忽略任何HUP
信号并一直挂起,直到您的程序终止,然后它将程序的退出状态返回给调用 shell。如果作业启动失败,要发送电子邮件,您可以这样做
即,启动您运行程序的后台子shell,然后测试返回的是126 还是127。如果找不到或无法启动命令
nohup
,它将执行此操作。java
这样的事情将更可靠地捕获您的进程的退出代码:
父.sh
等待
请注意,调用
wait
将无限期阻塞,因此,如果您需要对java
完成命令的时间量设置任意限制,您可以将调用替换为wait
循环并进行一些手动检查ps
以查看它,该过程仍在跑步。这将允许您设置一个看门狗并在进程挂起时将所有人从池中调用。诺胡普
如果您需要在不处于活动终端会话中的情况下运行 java 进程并处理其退出代码,请
nohup
不使用java
代码调用您的父脚本(上图)。父脚本可以被nohup
编辑,并且可以在没有控制终端的情况下在后台运行,并且可以可靠地进行电子邮件发送或清理。问题不一定是
nohup
命令,而是&
命令行末尾的问题。手册页
bash
说:从技术上讲,shell 派生出一个子 shell 来执行
nohup ...
命令,执行脚本的主 shell 立即继续执行脚本中的下一个命令。因此,当主 shell 执行该行之后的nohup ... &
行时,nohup 命令可能尚未退出:子 shell 可能正在加载它以执行。并且该
nohup
命令不一定就这样退出:它设置信号处理程序以忽略 HUP 信号,然后尝试直接exec()
执行该java ...
命令。如果exec()
系统调用成功,那么被nohup
转换成的进程java
没有fork()
新进程退出,所以还没有退出代码返回。nohup
实际命令返回退出代码的唯一方法是java
无法找到或执行该命令,或者该nohup
命令本身存在内部错误。如果exec()
系统调用成功,退出代码可用的唯一时间是java
命令本身结束时。这也是为什么尝试这样的事情并不能达到你想要的效果:
如果
nohup
在后台失败,wait
将获取其退出代码并允许对其进行检查;但是如果nohup
启动成功java
,那么wait
命令将一直等待直到java
退出,因为两者都nohup
将java
在同一个进程中一个接一个地运行。正如@datUser 建议的那样,您可能想做这样的事情:
请注意,我的脚本解决方案有一个固有的弱点:如果
nohup
ped 进程死亡而另一个进程在一秒钟内收到相同的 PID 号,则该脚本将无法注意到它不再是同一个进程。(但如果你的 PID 号码回收得那么快,你可能会遇到更大的问题。)为了最佳地解决问题,您需要脚本设置某种超时机制,该机制将
wait
在某个预定时间停止命令,然后wait()
在受监控的进程上运行系统调用(通过wait
shell 命令),因为这是只有被监视进程的实际父进程才能执行的操作。这在 shell 脚本中实现起来非常棘手。