在实验室里,大家都习惯通过ssh登录实验室的服务器进行coding,然后直接在服务器上执行任务(时间一般比较长),但有可能由于网络的不稳定或个人的不小心关掉了窗口而导致任务中断了。而如何使以ssh等方式登录服务器运行程序后,不因终端窗口关闭而中止程序的运行?
在Linux下有如下几种可以选择的方法。
1. nohup
当用户注销或者网络断开时,终端会收到HUP信号从而关闭其所有子进程。使用nohup可以使提交的命令忽略HUP信号。使用很简单,直接在要运行的命令前加上nohup即可。
# nohup command
然而,使用nohup的缺点就是:当遇到一些进程不属于接受HUP信号的终端的子进程,此时nohup就不起作用了。
2. setsid
使用setsid可以克服nohup的以上缺点,使用也非常方便,也只需在要处理的命令前加上setsid即可。
# setsid command
值得注意的是,使用setsid运行的命令的PPID是1(即init进程)。
3. &
将一个或多个命令包含在“()”中能让这些命令在子shell中运行。因此将“&”放入“()”中后,就无法通过jobs来查看。
# (command &)
而与setsid一样,新提交的进程的PPID也是1,因此不属于当前终端的子进程,从而不会受到当前终端的HUP信号的影响。
4. disown
前面三种方法都需要事先在命令前加上nohup或setsid,但如果在未加任何处理就提交了命令,前面三种方法就用不上了,disown能解决这个问题。
a) disown -h jobspec 使某个作业忽略HUP信号
b) disown -ah 使所有的作业都忽略HUP信号
c) disown -rh 使正在运行的作业忽略HUP信号
注意:当使用disown后,会将目标作业从作业列表中移除,即不能使用jobs来查看。
5. screen
disown有一个缺点就是当有大量的命令需要在稳定的后台运行时,要对每条命令都加上disown,解决这个问题的办法是使用screen。screen提供了ANSI/VT100的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。
a) screen -dmS session_name 建立一个处于断开模式下的会议
b) screen -list 列出所有会话
c) screen -r session_name 重新连接指定的会话
d) Ctrl + a,d 暂时断开当前会话
使用screen后,此时bash是screen的子进程,而screen是init的子进程。因此当ssh断开连接时,HUP信号不会影响到screen下面的子进程。可以使用pstree命令查看进程树来加深对screen,bash等的关系的了解。
阅读(1355) | 评论(0) | 转发(0) |