Shell使用技巧之后台进程退出

文章转载自http://leehomjan.iteye.com/blog/2146739点击打开链接

在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运行命令

Bash代码   收藏代码
  1. # nohup ./back.sh &  
  2. # nohup ./fore.sh  
  3. ^Z  
  4. [2]+  Stopped                 nohup ./fore.sh  
  5. # jobs   
  6. [1]-  Running                 nohup ./back.sh &  
  7. [2]+  Stopped                 nohup ./fore.sh  
  8. # ps -o pid,ppid,pgid,sid,cmd  
  9.   PID  PPID  PGID   SID CMD  
  10.  4766  4716  4766  4716 /bin/bash ./back.sh  
  11.  4769  4716  4769  4716 /bin/bash ./fore.sh  
  12. # fg  
  13. nohup ./fore.sh  
  14.   
  15. ### 关闭窗口并重新登录 ###  
  16.   
  17. # ps -eo pid,paid,pgid,sid,cmd |grep -E "back|fore"  
  18.  4766     1  4766  4716 /bin/bash ./back.sh  
  19.  4769     1  4769  4716 /bin/bash ./fore.sh  

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

值得注意的是nohup会在当前目录下产生一个nohup.out文件,并把实际命令的标准输出和标准错误重定向为nohup.out

 

2. 使用setsid运行命令

Bash代码   收藏代码
  1. # setsid ./back.sh &  
  2. # setsid ./fore.sh  
  3. # jobs   
  4. # ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"  
  5.  4871     1  4871  4871 /bin/bash ./back.sh  
  6.  4874     1  4874  4874 /bin/bash ./fore.sh  
  7.   
  8. ### 关闭窗口并重新登录 ###  
  9.   
  10. # ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"  
  11.  4871     1  4871  4871 /bin/bash ./back.sh  
  12.  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命令

Bash代码   收藏代码
  1. # ./fore.sh  
  2. ^Z  
  3. [2]+  Stopped   
  4. # jobs   
  5. [1]-  Running                 ./back.sh &  
  6. [2]+  Stopped                 ./fore.sh  
  7. # ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"  
  8.  5395  5361  5395  5361 /bin/bash ./back.sh  
  9.  5396  5361  5396  5361 /bin/bash ./fore.sh  
  10. # disown -h %2  
  11. # disown -a %1  
  12. # jobs   
  13. [2]+  Stopped                 ./fore.sh  
  14. # fg  
  15. ./fore.sh  
  16.   
  17. ### 关闭窗口并重新登录 ###  
  18.   
  19. # ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"  
  20.  5395  5361  5395  5361 /bin/bash ./back.sh  

重新登录后发现fore.sh还是被终止了,并且经过调查发现终了的原因是收到了SIGHUP信号。由此可见disown仅对后台进程起作用。

 

4.  Catch SIGHUP信号

如果是shell脚本,则在脚本中加上下面的一条语句就行了。

Bash代码   收藏代码
  1. # trap "" HUP  

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

C代码   收藏代码
  1. signal(SIGHUP, SIG_IGN);  

 

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

Bash代码   收藏代码
  1. # shopt -s huponexit 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值