在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种方法:

(在此声明,推荐使用exit退出,以下方法不一定管用,网上找的方法,未测试;第一种方法可能对一些进程有效,一些无效吧,至少我测试过,elasticsearch的kibana进程,nohup是无法阻止SIGHUP信号的)

1. 使用nohup运行命令

# nohup ./back.sh &
# nohup ./fore.sh
^Z
[]+ Stopped nohup ./fore.sh
# jobs
[]- Running nohup ./back.sh &
[]+ Stopped nohup ./fore.sh
# ps -o pid,ppid,pgid,sid,cmd
PID PPID PGID SID CMD
/bin/bash ./back.sh
/bin/bash ./fore.sh
# fg
nohup ./fore.sh ### 关闭窗口并重新登录 ### # ps -eo pid,paid,pgid,sid,cmd |grep -E "back|fore"
/bin/bash ./back.sh
/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"
/bin/bash ./back.sh
/bin/bash ./fore.sh ### 关闭窗口并重新登录 ### # ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"
/bin/bash ./back.sh
/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
[]+ Stopped
# jobs
[]- Running ./back.sh &
[]+ Stopped ./fore.sh
# ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"
/bin/bash ./back.sh
/bin/bash ./fore.sh
# disown -h %
# disown -a %
# jobs
[]+ Stopped ./fore.sh
# fg
./fore.sh ### 关闭窗口并重新登录 ### # ps -eo pid,ppid,pgid,sid,cmd |grep -E "back|fore"
/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

shell直接退出后 后台进程关闭的原因和对处的更多相关文章

  1. ssh连接断开后 shell进程退出

    问题描述:当SSH远程连接到服务器上,然后运行一个服务 ./catalina.sh start,然后把终端开闭(切断SSH连接)之后,发现该服务中断,导致网页无法访问.   解决方法:使用nohup命 ...

  2. Linux下java nohup 后台运行关闭后进程停止的原因,不挂断后台运行命令

    Linux下java nohup 后台运行关闭后进程停止的原因,不挂断后台运行命令 今天写sh脚本发现一终止命令程序就停止运行了,检查了很久才发现后面少了个&字符导致的!错误写法:nohup ...

  3. 单片机main函数退出后发生什么——以stm32为例

    STM32:main函数退出后发生什么? 我们都在说单片机要运行在无限循环里,不能退出,可退出之后会发生什么? 讨论STM32启动过程的文章数不胜数,可main函数结束之后会发生什么却少有讨论. 几日 ...

  4. silverlight 退出系统(关闭当前网页),通过调用JS

    确认后直接退出系统,关闭当前页面 页面部分: <HyperlinkButton x:Name="LinkExit" Style="{StaticResource L ...

  5. eclipse 导出Runnable JAR file ,双击无法执行原因与解决 双击后闪退的原因 批处理java打包文件 @echo off start javaw -jar *.jar

    eclipse 导出Runnable JAR file 导出后如果系统没有JRE,双击无法运行,需要用命令方法 安装后解决,如图 双击后闪退的原因,通过执行 java -jar TingGe.jar ...

  6. vue 首次加载缓慢/刷新后加载缓慢 原因及解决方案

    # vue 首次加载缓慢/刷新后加载缓慢 原因及解决方案 最近做项目发现一个问题,页面每次刷新后加载速度都非常慢,20s左右,在开发环境则非常流畅,几乎感觉不到,本文参考望山的各种方案优化 1,关闭打 ...

  7. Docker退出容器不关闭容器的方法

    进入docker容器后如果退出容器,容器就会变成Exited的状态,那么如何退出容器让容器不关闭呢? 如果要正常退出不关闭容器,请按Ctrl+P+Q进行退出容器,这一点很重要,请牢记! 以下示例为退出 ...

  8. Linuxqq shell脚本安装后的卸载

    官方下载和帮助页面: 传送门 linuxqq_2.0.0-b1 的时候,并没有发布 MIPS64 的 DEB 包,只能用 .sh 安装,需要手动删除卸载.愚人节发布的 beta2 新增了 MIPS64 ...

  9. Linux 进程退出后自动启动

    /********************************************************************** * Linux 进程退出后自动启动 * 说明: * 在系 ...

随机推荐

  1. 解析Ceph: 数据的端到端正确性和 Scrub 机制

    转自:https://www.ustack.com/blog/ceph-internal-scrub/ Ceph 的主要一大特点是强一致性,这里主要指端到端的一致性.众所周知,传统存储路径上从应用层到 ...

  2. tsne pca 自编码器 绘图(CC2)——一定记得做无量纲化处理使用standardscaler,数据聚类更明显

    tsne 数据不做预处理: # coding: utf-8 import collections import numpy as np import os import pickle from skl ...

  3. php中实现将姓名拆分为姓氏和名字

    之前有分享了用javascript在客户端进行姓名拆分的方法,后应项目需要,又用PHP实现了,贴出来 跟大家分享交流: /** * 把全名拆分为姓氏和名字 * @param string $fulln ...

  4. hdu-2544-最短路(Floyd算法模板)

    题目链接 题意很清晰,入门级题目,适合各种模板,可用dijkstra, floyd, Bellman-ford, spfa Dijkstra链接 Floyd链接 Bellman-Ford链接 SPFA ...

  5. Python ord()与chr()函数

    chr():十进制或十六进制数(0-255)转成对应的ASCII字符. ord():ASCII字符转成对应的十进制数. 一个小性质:ASCII表中大写字母排在前面小写排在后面,相差32. 比如: or ...

  6. CANopenSocket CANopenCommand.c hacking

    /***************************************************************************** * CANopenSocket CANop ...

  7. OpenCV - opencv3 图像处理 之 图像缩放( python与c++实现 )

    转自:https://www.cnblogs.com/dyufei/p/8205121.html 一. 主要函数介绍 1) 图像大小变换 cvResize () 原型: voidcvResize(co ...

  8. tag问题

  9. @media screen页面自适应尺寸!!

    @media screen and (max-width:360px){body,input,select{font-size:38%}} @media screen and (min-width:3 ...

  10. bzoj 3887: Grass Cownoisseur Tarjan+Topusort

    题目: 给一个有向图,然后选一条路径起点终点都为1的路径出来,有一次机会可以沿某条边逆方向走,问最多有多少个点可以被经过?(一个点在路径中无论出现多少正整数次对答案的贡献均为1) 题解: 首先考虑简单 ...