我使用以下脚本重新启动在 Solaris Sun 5.10 机器上运行的 Java 服务器...
pkill -9 java
nohup ./start_java.sh &
tail -f smx.log
我SSH
到该框(使用Putty
)来运行脚本。
只要我在关闭 Putty 之前ctrl-c
退出, 它就可以正常工作tail -f
。如果我不停止尾部(只需关闭 Putty 窗口),它就会终止该start_java
进程。
此后,我修改了脚本以删除tail -f
,但我很困惑为什么会发生这种情况?
答案1
编写一个脚本来执行以下操作:
#!/bin/bash
trap 'echo hup' hup
trap 'echo int' int
trap 'echo quit' quit
trap 'echo abrt' abrt
trap 'echo kill' kill
trap 'echo usr1' usr1
trap 'echo usr2' usr2
trap 'echo term' term
trap 'echo chld' chld
trap 'echo cont' cont
trap 'echo stop' stop
trap 'echo tstp' tstp
trap 'echo ttin' ttin
trap 'echo ttou' ttou
shopt huponexit
sleep 10
echo $(date) process $$ done
编写第二个脚本来执行: > nohup.out; nohup firstscript& echo sleeping; sleep 10
。运行第二个脚本,等待一两秒,然后关闭 PuTTY 终端。打开一个新的 PuTTY 终端并检查 nohup.out 文件。它应该会告诉您第一个脚本收到什么信号导致其停止。这将帮助您弄清楚如何继续。您可以尝试做trap '' THEGUILTYSIGNAL
一件事。
它还应该告诉您 huponexit 值。如果启用了该值,您可以尝试一下shopt -u huponexit
,看看是否能改善情况。(改善 = 您可以运行第二个脚本,然后关闭 PuTTY 终端,但第一个脚本仍会运行完成。)
答案2
Nohup 应该可以工作,但根据我的经验,有时客户端实际上会使用 sigkill 而不是 sighup,因此它最终会终止您的进程,而不是仅仅告诉它们挂断(就像 nohup 阻止的那样)。Screen 是解决该问题的一种可能方法,因为它会忽略 sigkill,但它也有自己的问题,您必须解决这些问题。
可能是正在运行的进程导致您的终端(或 Putty)发送 sigkill。
答案3
虽然screen
这可能是处理此问题的最佳方法,但如果您使用 编写脚本bash
,则有一种替代方法是disown
start_java.sh
启动进程后,它会将进程与终端分离,因此当您关闭 PuTTY 时,发送给正在运行的进程的任何 SIGKILL 都不会发送给该进程。
另一种方法是使用tcsh
,它会自动不认退出时清除后台进程,而不是用 SIGKILL 来杀死它们。
我思考您可以disown
像这样添加到您的脚本中:
#!/bin/bash
# might need to specify bash in the line above for this to work right
pkill -9 java
nohup ./start_java.sh &
disown
tail -f smx.log