设为首页 收藏本站
查看: 1137|回复: 0

shell退出后 后台进程关闭的原因和对处

[复制链接]

尚未签到

发表于 2017-5-16 08:30:15 | 显示全部楼层 |阅读模式
在linux上进行测试时发现启动后台进程后,如果使用exit退出登录shell,shell退出后后台进程还是能够正常运行,但如果直接关闭登陆的窗口(如直接关掉xshell),那后台进程就会一起终了。都是退出登录为什么前者后台进程会退出,而后者不会退出呢?
在查看bash的manual时发现有如下一段描述:
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而终止运行。
那能不能通过设置,在窗口异常关闭时保持后台进程继续运行呢?
答案是肯定的,一般有如下4种方法:
1. 使用nohup运行命令

# nohup ./back.sh &
# nohup ./fore.sh
^Z
[2]+  Stopped                 nohup ./fore.sh
# jobs
[1]-  Running                 nohup ./back.sh &
[2]+  Stopped                 nohup ./fore.sh
# ps -o pid,ppid,pgid,sid,cmd
PID  PPID  PGID   SID CMD
4766  4716  4766  4716 /bin/bash ./back.sh
4769  4716  4769  4716 /bin/bash ./fore.sh
# fg
nohup ./fore.sh
### 关闭窗口并重新登录 ###
# ps -eo pid,paid,pgid,sid,cmd |grep -E "back|fore"
4766     1  4766  4716 /bin/bash ./back.sh
4769     1  4769  4716 /bin/bash ./fore.sh
发现重新登录后前台和后台进程都还运行着但父进程变成了init。
值得注意的是nohup会在当前目录下产生一个nohup.out文件,并把实际命令的标准输出和标准错误重定向为nohup.out
 
2. 使用setsid运行命令

# setsid ./back.sh &
# setsid ./fore.sh
# jobs
# ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"
4871     1  4871  4871 /bin/bash ./back.sh
4874     1  4874  4874 /bin/bash ./fore.sh
### 关闭窗口并重新登录 ###
# ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"
4871     1  4871  4871 /bin/bash ./back.sh
4874     1  4874  4874 /bin/bash ./fore.sh
可以发现在使用setsid后,不能在当前登录shell的jobs中找到back.sh和fore.sh。并且由于在退出前back.sh和fore.sh的父进程已经是init,重新登录后back.sh和fore.sh没有发生任何改变。
 
3. 使用disown命令

# ./fore.sh
^Z
[2]+  Stopped
# jobs
[1]-  Running                 ./back.sh &
[2]+  Stopped                 ./fore.sh
# ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"
5395  5361  5395  5361 /bin/bash ./back.sh
5396  5361  5396  5361 /bin/bash ./fore.sh
# disown -h %2
# disown -a %1
# jobs
[2]+  Stopped                 ./fore.sh
# fg
./fore.sh
### 关闭窗口并重新登录 ###
# ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"
5395  5361  5395  5361 /bin/bash ./back.sh
重新登录后发现fore.sh还是被终止了,并且经过调查发现终了的原因是收到了SIGHUP信号。由此可见disown仅对后台进程起作用。
 
4.  Catch SIGHUP信号
如果是shell脚本,则在脚本中加上下面的一条语句就行了。

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

signal(SIGHUP, SIG_IGN);
X. 当然相反的我们也可以让shell在exit退出时发送SIGHUP给所有的jobs,具体设置如下:

# shopt -s huponexit
 

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-377877-1-1.html 上篇帖子: Android 使用adb shell命令时出现sqlite3 : not found 问题 解决方法 下篇帖子: 几个shell快捷键
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表