进程Java仍然被杀死


11

我需要在大学服务器上运行Java程序。我正在通过ssh通过他们的服务器远程登录

所以我像这样使用nohup:

nohup java -jar project.jar &

但是,当我注销并关闭终端然后重新登录到服务器时,我的进程丢失/丢失了。


尝试重定向stdoutstderr一些文件-过程可能会通过信号比其他SIGHUP,试图写一个封闭的终端时被杀死stdout/ stderr。例如>/dev/null 2>&1&职位签收之前添加到您的命令中。
鲍里斯·伯科夫

1
@Bob不需要nohup-大多数实现默认情况下都会这样做,尽管可能需要重定向stdineg </dev/null
Graeme 2014年

Answers:


14

nohup不仅使程序免疫SIGHUPSIGQUIT信号。当您从会话注销时,现代shell可能会发送其他信号,因此无法保证您的程序不会被杀死,甚至无法在Windows下运行nohup

更好的解决方案是使用tmuxscreen,或者如果使用bash,可以尝试:

$ java -jar project.jar &
$ disown

如果您使用disown,则需要手动重定向,例如添加</dev/null &>/dev/null
Graeme 2014年

@Graeme:我认为,如果我们不再使用外壳程序(只需运行命令并退出),则无需重定向。
cuonglm

尝试ssh localhost 'sleep 10m & disown'bash不会退出。
Graeme 2014年

好的,ssh如果有程序连接到终端,似乎不会退出。但是,如果以交互方式运行,则上面的方法很好。
Graeme 2014年

的Linux(GNU coreutils和busybox)和BSD实现nohup不能使命令不受干扰SIGQUIT,而只能使不受干扰SIGHUP。这将明显违反标准,并且AFAIK可能仅在Solaris(某些版本?)上发生。
mosvy

13

替代(慢性功能障碍)的另一种选择nohup

setsid java -jar project.jar </dev/zero &>/dev/null &

这有效地“守护”了该过程。现在它已归init所有,因此永远不会HUP,它的I / O流是安全的,并且已被分叉到后台。

请参阅man setsid以获取更多信息。不同于screentmux,这不是一个拥有所有权并可以继续运行的程序。它只是在自己的进程组中启动程序。


为什么nohup功能失调?
cpugeniusmv 2014年

@cpugeniusmv我确定它对某些事情很有用,但是,出于通常建议的目的,登录某个地方,启动一个进程并注销(类似于OP),我发现它并不可靠。我想这可能是滥用,也许setsid以此方式更能说明问题。它跳过了nohup隐含的步骤(将进程重新初始化为孤立的init作为父进程)。 nohup如果您以后可能希望先完成该工作,它将更加灵活。
goldilocks 2014年

@ TAFKA'goldilocks'我认为问题出在处理stdin,stdout和stderr,这不是由nohup真正(但部分(!))处理的。Nohup很好地完成了主要工作,从而使该过程不受SIGHUP的影响。但是流中有很多事情可能出错,或者更糟糕的是,有时会出错,具体取决于缓冲区大小。我会说,不是nohup错了,但是期望nohup会做什么。
Volker Siegel


-2

尝试使用STDOUT和STDERR重定向到null来运行nohup:

nohup java -jar project.jar 2>&1 &

1
您只将stderr重定向到stdout,这不会改变nohup的工作方式(它将两者都重定向到nohup.out)。
吉尔斯(Gilles)'所以

1
-1,我认为您的意思是,nohup java -jar project.jar 2>/dev/null &但您显然不知道自己在做什么。甚至更好,也要喂stdin /dev/null
PlasmaPower

@PlasmaPower在这里,您有+1。祝您有美好的一天:)
鲍里斯·奎罗兹(Boris Quiroz)2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.