软硬件环境
- ubuntu 18.04 64bit
- nohup
- setsid
- screen
简介
经常会碰到这样的问题,用
ssh
登录远程的
Linux
服务器,运行了一些耗时的任务,结果却由于网络的不稳定导致任务中途失败。如何让命令提交后不受本地关闭终端窗口或者网络断开连接的干扰呢?本文介绍一些应对方法,您可以针对不同的场景选择不同的方式来处理这个问题。
解决方法
当用户注销(
logout
)或者网络断开时,终端会收到
HUP
(
hangup
)信号从而关闭其所有子进程。由此可以想到,我们的解决办法有两种途径:要么让进程忽略
HUP
信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。
nohup
我们第一个想到的方法就是
nohup
,顾名思义,
nohup
的用途就是让提交的命令忽略
hangup
信号,命令是使用也是非常的简单,只要在你要执行的任务之前加上
nohup
即可,标准输出和标准错误缺省会被重定向到
nohup.out
文件中
nohup ping 192.168.1.1

此时
nohup.txt
文件内容如下
关闭
ssh
连接,然后重新登录,发现
ping
的进程还在后台运行
setsid
如果我们的进程不属于接受
HUP
信号的终端的子进程,那么自然也就不会受到
HUP
信号的影响了,
setsid
就能帮助我们做到这一点。
setsid
使用跟
nohup
非常类似,加在任务命令之前就可以了
setsid ping 192.168.1.1
通过命令
ps -ef | grep ping
,可以看到
ping
进程的进程号是5209,父进程的进程号是1,在
linux
系统中,1是
init
进程的进程号。此时的
ssh
进程号是
screen
screen
提供了
ANSI/VT100
的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。
screen
的参数很多,具有很强大的功能,我们在此仅介绍其常用功能,更纤细的使用方法请参阅其帮助文档。
ubuntu
中安装
screen
sudo apt install screen
screen
常用命令
- screen -dmS test 创建一个名叫test的处于断开模式下的会话
- screen -list 来列出所有会话
- screen -r test 重新连接test会话
当我们用
-r
连接到
screen
会话后,我们就可以在这个伪终端里面为所欲为,再也不用担心
HUP
信号会对我们的进程造成影响,也不用给每个命令前都加上
nohup
或者
setsid
了
screen -dmS xgxscreen -r xgxping 192.168.1.1
此时用
pstree
查看
可以看到
ping
进程是
screen
的子进程,而
screen
是
init
的子进程,那么当
ssh
断开连接时,
HUP
信号自然就不会影响到
screen
下面的子进程了
参考资料
- https://www.gnu.org/software/screen/