关闭Terminal为什么会中断
根据IBM科普文章任何一个Terminal窗口连接上服务器都会存在一个进程(Process),并且存在一个会话(Session)在此线程下
可以使用ps -f 查看, 其中f参数的意思为打印出 PID(Process ID), PPID(Parent Process ID)
1 | -f Display the uid, pid, parent pid, recent CPU usage, process start time, controlling tty...... |
那么如果关闭Terminal或者网络链接断开,会有一个SIGHUP信号发送到该线程,让此PID下的所有任务中止
什么是SIGHUP信号
SIGHUP信号是众多POSIX信号的一个, 像程序Crash时常见的两个信号 SIGABRT (”abort”, abnormal termination.) 和 SIGSEGV ( “segmentation violation”, invalid memory access.) 都属于同类
1 | hangup 名称的来由 |
如何躲避Hang Up(HUP)信号
躲避SIGHUP一般分为两个策略
- 直接屏蔽SIGHUP信号,使用nohup命令
- 让某个命令运行在另外一个PID下,使用setsid命令,或者直接使用 (shell &)
1 | nohup - run a command immune to hangups, with output to a non-tty |
使用nohup指令的要点
- 命令的stdout会默认存在 nohup.out 中, 也可以重定向到其他文件
- nohup本身只是中断信号,并不会让出当前termianl的stdin,所以要在结尾加入 &
1 |
|
使用setsid指令的要点
使用setsid可以让命令运行在另外一个进程里,或通过()可以让某些命令直接运行在子进程立,作用和setsid是一样的
1 |
|
可以通过ps指令查看 pid 和 ppid 之间的关系
1 |
|
如果处理已经开始执行的命令
如果一个指令已经开始运行,无法使用 nohup 和 setsid 来躲避SIGHUP信号,需要使用另外一个指令 disown
- 用disown -h jobspec来使某个作业忽略HUP信号
- 用disown -rh 来使正在运行的作业忽略HUP信号
还需要使用到组合命令包括
- CTRL+Z : 挂起(Suspend)就是临时暂停当前stdout中在执行的任务
- jobs : 查看当前有哪些任务在运行
- bg : 把某个任务放入后台,但是并没有对SIGHUP进行处理
- %1 : jobspec 任务描述符,用来指定任务
那么我们可以通过以上指令的组合,来达到让某个任务躲开SIGHUP
1 | # 执行一个任务 |
一劳永逸使用screen命令产生虚拟终端
Screen命令可以创建一个虚拟终端,相当于不用重新链接再开一个终端了,需要用到遗下四个指令
- screen -dmS name :创建一个虚拟终端。
- screen -list : 来列出所有会话。
- screen -r name : 来重新连接(Attach)指定会话。
- CTRL+A D : 组合快捷键从虚拟终端暂时断开(Detach)
1 |
|
从第一个指令参数 -dmS 代表以下三个含义
1 | # -d 从创建的Terminal detach出来 |