解决XShell退出后,后台进程关闭

问题描述

利用 XShell 登录远程 Unix 服务器,启动后台进程,如下所示。

$ command &

当关闭 XShell 后,后台进程就会一起终止。

问题原因

在查看 Bash 的使用手册后,发现如下一段描述:

The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. Stopped jobs are sent SIGCONT to ensure that they receive the SIGHUP.

由此可以知道后台进程退出是由于登陆 shell 收到了 SIGHUP 信号后在退出前将 SIGHUP 转发给所有的作业(jobs)。jobs 由于收到 SIGHUP 而终止运行。

解决方案

如果我们不想因为关闭 XShell 而导致自己的后台进程结束。一般有以下几种方法。

使用 nohup 运行命令

iZbp16mnrxv8swew70ltcdZ# nohup python3 csdn1.py > /dev/null &
[1] 8467
iZbp16mnrxv8swew70ltcdZ# nohup: ignoring input and redirecting stderr to stdout
iZbp16mnrxv8swew70ltcdZ# jobs
[1]  + running    nohup python3 csdn1.py > /dev/null
iZbp16mnrxv8swew70ltcdZ# ps -o pid,ppid,pgid,sid,cmd
  PID  PPID  PGID   SID CMD
 8220  8197  8220  8220 -zsh
 8467  8220  8467  8220 python3 csdn1.py
 8470  8220  8470  8220 ps -o pid,ppid,pgid,sid,cmd
iZbp16mnrxv8swew70ltcdZ# fg 
[1]  + running    nohup python3 csdn1.py > /dev/null
^Z
zsh: suspended  nohup python3 csdn1.py > /dev/null

关闭 XShell 窗口并重新登录。


iZbp16mnrxv8swew70ltcdZ# ps -aux | grep csdn1.py
root      8467  3.2  5.7 116352 58256 ?        SN   13:27   0:29 python3 csdn1.py
root      8560  0.0  0.0  14224  1000 pts/0    S+   13:42   0:00 grep csdn1.py

发现重新登录后前台和后台进程都还运行着但父进程变成了init。

使用 setpid 运行命令

iZbp16mnrxv8swew70ltcdZ# setsid python3 csdn1.py > /dev/null &
[1] 8584
iZbp16mnrxv8swew70ltcdZ# 
[1]  + done       setsid python3 csdn1.py > /dev/null
iZbp16mnrxv8swew70ltcdZ# ps
  PID TTY          TIME CMD
 8546 pts/0    00:00:00 zsh
 8587 pts/0    00:00:00 ps
iZbp16mnrxv8swew70ltcdZ# ps -aux | grep csdn1
root      8585 20.6  5.5 115340 56796 ?        SNs  13:45   0:04 python3 csdn1.py
root      8589  0.0  0.0  14224   984 pts/0    S+   13:45   0:00 grep csdn1

关闭 XShell 窗口并重新登录。

Last login: Sun Feb  9 13:41:21 2020 from 115.226.144.198
iZbp16mnrxv8swew70ltcdZ# ps -aux | grep csdn1
root      8585 21.3  5.6 115492 57276 ?        SNs  13:45   0:12 python3 csdn1.py
root      8619  0.0  0.0  14224   892 pts/1    S+   13:46   0:00 grep csdn1

使用 disown 运行命令

### 先运行脚本,在用ctrl+z挂起脚本,通过jobs查看,脚本确实处于suspended状态 ###
iZbp16mnrxv8swew70ltcdZ# python3 csdn1.py > /dev/null
^Z
zsh: suspended  python3 csdn1.py > /dev/null
iZbp16mnrxv8swew70ltcdZ# jobs
[1]  + suspended  python3 csdn1.py > /dev/null

### 使用bg命令将挂起的任务转到后台运行 ###
iZbp16mnrxv8swew70ltcdZ# bg %1
[1]  + continued  python3 csdn1.py > /dev/null
iZbp16mnrxv8swew70ltcdZ# jobs
[1]  + running    python3 csdn1.py > /dev/null

### 使用disown命令,再次利用job查看发现后台任务变成daemon了 ###
iZbp16mnrxv8swew70ltcdZ# disown %1   
iZbp16mnrxv8swew70ltcdZ# jobs
iZbp16mnrxv8swew70ltcdZ# ps -aux | grep csdn1
root      8628 14.9  5.5 114524 56596 pts/1    S    13:49   0:19 python3 csdn1.py
root      8631  0.0  0.0  14224   952 pts/1    S+   13:51   0:00 grep csdn1

关闭 XShell 窗口并重新登录。

Last login: Sun Feb  9 13:46:15 2020 from 115.226.144.198
iZbp16mnrxv8swew70ltcdZ# jobs
iZbp16mnrxv8swew70ltcdZ# ps -aux | grep csdn1.py
root      8628 19.6  5.9 118648 60508 ?        S    13:49   1:05 python3 csdn1.py
root      8684  0.0  0.0  14224   996 pts/0    S+   13:55   0:00 grep csdn1.py

Catch SIGHUP 信号

如果是shell脚本,则在脚本中加上下面的一条语句就行了。(备注,这个命令测试没有成功

# trap "" SIGHUP

如果是C程序,则使用signal函数对SIGHUP进行屏蔽就行了。

signal(SIGHUP, SIG_IGN);
发布了138 篇原创文章 · 获赞 7 · 访问量 41万+

猜你喜欢

转载自blog.csdn.net/justidle/article/details/104233141
今日推荐