文档章节

linux:nohup 命令实现守护进程(屏蔽 SIGHUP 信号)

big_cat
 big_cat
发布于 2017/01/19 12:05
字数 1094
阅读 2.1K
收藏 0

我们先了解一下 SIGHUP信号和 nohup命令的一些知识点:

SIGHUP 信号

1、终端关闭时,该信号被发送到 session 首进程以及作为 job 提交的进程(即用 & 符号提交的进程)

2、session首进程退出时,该信号被发送到该 session 中的前台进程组中的每一个进程,但不会发送给 job  提交的进程。

3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。

终端关闭的情景如断网或者手动关闭了会话窗口,这时即便你的命令 & 了,仍然会被 SIGHUP 信号中断。

Exit 和 Logout 命令

session 首进程退出则是你使用 exit 或者 logout 命令正常,这种退出并不会向 & 的任务发送 SIGHUP 信号

NOHUP 命令

而 nohup 命令则是应对终端异常断掉时的场景,当我们使用 nohup command & 将任务切换到后台执行时,即便此时终端突然断掉,SINHUP 信号也会被 nohup 屏蔽掉而不会终止你的后台任务。

1、bg / fg / jobs 和 ctrl-z / & 的联用

注意:当任务被 & 到后执行时,你使用 exit 或者 logout 正常登出只会结束前台命令,并不会终止你后台任务。但如果你直接关闭会话窗口或者意外断网,系统都会向当前会话下的进程发送 SIGHUP 信号。而进程对此信号的默认处理方式是退出执行。

当想要将程序后台运行时,你可以在运行命令时使用:

# 使用 & 将其挂到后台任务队列 会返回任务编号
command &
# 使用 fg 则可以将任务队列中的任务切换到前台来 可以根据任务编号选取 默认是最新的任务
fg
#或者运行命令后 ctrl-z bg 将其挂载到后台任务队列
command
#会获取任务编号 将任务暂停
ctrl-z
#bg 后面可以加任务编号 默认是将最新的任务挂载到后台任务队列
bg
# 使用 jobs 可以查看任务队列的状态
jobs

# 将第二个任务切换到前台
fg 2

# 将其重新挂载到后台
ctrl-z
bg

exit 或者 logout 后 & 进程并不会被中断

断网或者关闭窗口 & 进程也会被中断

可以看到这个会话里两个后任务没了,那是因为我强关了开启这两任务的窗口,SIGHUP 信号会发给后台任务

2、nohup 则是可以将任务以不挂断的方式运行(不挂断是说任务不接收 SIGHUP 信号)

这里说的不挂断是说当我们用 & ctrl-z + bg 等命令将任务挂在后台执行时,如果网络中断或窗口被关闭的话,系统会发送 SIGHUP 信号到你的所有任务,即便他们是以后台 & 方式运行

如果我们使用了 nohup 命令,则会将 SIGHUP 命令屏蔽掉,不会被终端

#后台运行
nohup ./test.sh &

#挂载到后台
nohup ./test.sh
ctrl-z
bg

看着其实和上面讲的没什么区别,此时别说你正常的使用 exit 或 logout 正常登出,就算突然断网或者关闭窗口任务也不会被终止。

在3会话开启的 nohup 后台任务,然后关掉窗口

可以看到我关闭了3会话(呃,他编号就跟进了一位,4变成3了...),但任务仍然在运行,如果我不使用 nohup,这两任务就中断了...

总结:

1、exit 或 logout 正常登出并不会终止 & 的后台任务,此时的 SIGHUP 信号只会发给前台任务

2、关闭窗口或断网,前后台任务都会收到 SIGHUP 信号,但如果我们试用了 nohup 则可以屏蔽此信号,让任务仍不被中断。

3、进程收到 SIGHUP 信号时默认的操作是退出执行。但我们可以在代码里使用信号捕捉的方法,捕捉或忽略 SIGHUP 信号的处理,这样进程就不会退出了。

© 著作权归作者所有

big_cat
粉丝 50
博文 239
码字总数 163220
作品 0
长宁
后端工程师
私信 提问
加载中

评论(0)

ssh 关闭后仍保持当前运行的进程

ssh 关闭后仍保持当前运行的进程 由于各种原因,需要通过ssh登录linux或者unix主机,很多时候我们需要通过ssh的终端启动一 些服务或者运行一些程序,但是默认情况下,当我们关闭ssh终端连接,...

今幕明
2014/11/06
3.4K
1
Linux后台运行命令,nohup和&的区别

&的意思是在后台运行, 什么意思呢? 意思是说, 当你在执行 ./a.out & 的时候, 即使你用ctrl C, 那么a.out照样运行(因为对SIGINT信号免疫)。 但是要注意, 如果你直接关掉shell后, 那么...

宇的季节
2018/03/11
0
0
linux守护进程、SIGHUP与nohup详解

前端时间帮忙定位个问题。docker容器故障恢复后,其中的keepalived进程始终无法启动,也看不到Keepalived的日志。 strace 查看系统调用之后,发现了原因所在 1 socket(PFLOCAL, SOCKDGRAM|SO...

吕亚辉
2017/08/18
0
0
Linux命令nohup+screen

如果想在关闭ssh连接后刚才启动的程序继续运行怎么办,可以使用nohup。但是如果要求第二天来的时候,一开ssh,还能查看到昨天运行的程序的状态,然后继续工作,这时nohup是不行了,需要使用s...

squanchao
2016/06/29
70
0
实现Linux Daemon 进程

如果我们远程登录了远程的 Linux 服务器,运行了一些耗时较长的任务,如何让命令提交后不受本地关闭终端窗口/网络断开连接的干扰呢? 守护进程 守护进程,也即通常所说的 Daemon 进程,是 Linu...

wynwyy
2016/09/11
3K
12

没有更多内容

加载失败,请刷新页面

加载更多

springcloud微服务实战_04_服务消费者

4.1 客服端负载均衡 Ribbon 通过上一篇《Spring Cloud构建微服务架构:服务消费》,我们已经学会如何通过LoadBalancerClient接口来获取某个服务的具体实例,并根据实例信息来发起服务接口消费...

SP_K
26分钟前
70
0
pandas操作excel操作-06-数据排序操作

import pandas as pdbooks = pd.read_excel('D:/output.xlsx', index_col='idx')# 按照SinglePrice排序books.sort_values(by='SinglePrice', inplace=True, ascending=False)# 按照T......

烽焱10仴
29分钟前
79
0
如何找到该日期的最后一天?

如何在PHP中获取本月的最后一天? 鉴于: $a_date = "2009-11-23" 我想要2009-11-30; 给定 $a_date = "2009-12-23" 我想2009-12-31。 #1楼 你的解决方案在这里.. $lastday = date('t',strt......

javail
31分钟前
45
0
【剑指Offer】链表——复杂链表的克隆

package cn.dzp.flyroc.offer; //定义复杂链表 class ComplexList{ int val; ComplexList next = null; ComplexList random = null; ......

大数据健身侠
40分钟前
62
0
数据结构与算法系列六(栈)

1.引子 1.1.为什么要学习数据结构与算法? 有人说,数据结构与算法,计算机网络,与操作系统都一样,脱离日常开发,除了面试这辈子可能都用不到呀! 有人说,我是做业务开发的,只要熟练API...

yhhitall
今天
51
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部