背景

由于Linux的某些特性,例如可以多用户同时登陆、服务器运用广泛等,我们通常会用ssh去连接一台远程的Linux主机,或者在开发机上(本机)开多个terminal。而在我们运行一个耗时较长的任务时,如果因为网络原因,或其他未知异常导致终端连接断开,那我们的任务随即也会被kill掉。这是因为当你连接断开的时候,终端会收到一个SIGHUP信号,进而终端当前进程下的所有子进程,所以与之相关的任务将全被kill。而我们很多情况下想要的是在意外发生的时候,任务继续跑而不受父进程的影响。

元凶:SIGHUP 信号

让我们来看看为什么关掉窗口/断开连接会使得正在运行的程序死掉。

在Linux/Unix中,有这样几个概念:

进程组(process group):一个或多个进程的集合,每一个进程组有唯一一个进程组ID,即进程组长进程的ID。

会话期(session):一个或多个进程组的集合,有唯一一个会话期首进程(session leader)。会话期ID为首进程的ID。

会话期可以有一个单独的控制终端(controlling terminal)。与控制终端连接的会话期首进程叫做控制进程(controlling process)。当前与终端交互的进程称为前台进程组。其余进程组称为后台进程组。

根据POSIX.1定义:

挂断信号(SIGHUP)默认的动作是终止程序。

当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)。

如果会话期首进程终止,则该信号发送到该会话期前台进程组。

一个进程退出导致一个孤儿进程组中产生时,如果任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中所有进程。

因此当网络断开或终端窗口关闭后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出。

解决方案

未雨绸缪派

nohup

通过背景分析,我们很容易想到,如果捂住终端的眼睛(让终端忽略SIGHUP信号),是不是就不会干掉子进程了?nohup就是干这样一件事情,其用法也很简单,命令前加上nohup即可:

nohup command &

示例:

➜ ~ nohup python -m SimpleHTTPServer 8421 &

[1] 7533

appending output to nohup.out

➜ ~ ps -ef | grep 7533

501 7533 6838 0 9:39AM ttys003 0:00.06 python -m SimpleHTTPServer 8421

501 7613 6838 0 9:39AM ttys003 0:00.00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn 7533

➜ ~ ls -al nohup.out

-rw------- 1 vien staff 0 Aug 30 09:39 nohup.out

说明:

1.后缀&是让其后台运行,但注意,后台运行不代表不受SIGHUP信号影响,连接断开的话依然会终止任务。

2.我们可以看到下面的appending output to nohup.out,然后在最后我列出了这个文件,可以看到就是刚刚创建的。任务所有的输出都将输出到这个文件中,当然也可以自定输出路径、文件名、内容等。

3.然后中间我列出了这个进程,可以观察到,其父进程ID与当前窗口下的进程ID是相同的6838 ,也就是说这个任务还是隶属于当前进程,这将与下面的方法有所不同。

重定向输出位置:nohup command > vienout.log 2>&1 &

由于使用nohup时,会自动将输出写入nohup.out文件中,如果文件很大的话,nohup.out就会不停的增大,我们可以利用Linux下一个特殊的文件/dev/null来解决这个问题,这个文件就相当于一个黑洞,任何输出到这个文件的东西都将消失

只保留输出错误信息 nohup command >/dev/null 2>err.log &

所有信息都不要 nohup command >/dev/null 2>&1 &

这里解释一下后面的2>&1 。 这涉及到Linux的重定向,其中0、1、2分别是标准输入、标准输出、标准错误输出,用来指定需要重定向的标准输入输出。默认情况下是标出输出,也就是1 。例如我们而上文提到的 2>&1 是 将错误信息重定向到标准输出。

setsid

上面讲的忽略SIGHUP信号,那如果我们给它(任务)换个爹(父进程)呢?这时候我们就可以用到setsid ,用户与上一个一样简单:

setsid command

示例:

➜ ~ setsid ping google.com

...(省略输出)

➜ ~ ps -ef | grep ping

moma 6186 1 0 09:55 ? 00:00:00 ping google.com

moma 8681 7988 0 09:59 pts/37 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn ping

说明:

1.我们可以看到这里任务的父进程ID变成了1,也就是init进程,这样它爹就不会轻易挂掉了。

2.之所以省略了若干输出,是因为输出太多了,没有重定向导入/dev/null或者别的地方,可想而知,人家亲爹不要,换个了有钱的干爹,你再骂他说:“你个龟儿子,不听老子话,就不给你零花钱”,当然不会鸟你了,也就是你的Ctrl+C之类的命令都是不可用的,你签字(回车)的那一刻,这儿子就归别人了。

说明:setsid命令在Mac系统下是不存在的

() + &

江湖中传闻一个关于 subshell 的小技巧。我们知道,将一个或多个命名包含在“()”中就能让这些命令在子 shell 中运行中,从而扩展出很多有趣的功能。

当我们将"&"也放入“()”内之后,我们就会发现所提交的作业并不在作业列表中,也就是说,是无法通过jobs来查看的。

(ping command &)

这里就不做示例,通过上面两个例子这个很容易就是用了。而且这个基本跟第二个一样,也是换爹。

亡羊补牢派

刚刚讲的那些都是任务开始前搞事情,那么万一我们脑子一抽,手一抖,没有任何安全措施就一下子回了车呢?莫慌,还有这种操作。

disown

使某个作业忽略SIGHUP信号

disown jobspec

示例:

➜ ~ python -m SimpleHTTPServer 8877 &

[1] 20815

➜ ~ Serving HTTP on 0.0.0.0 port 8877 ...

➜ ~ jobs

[1] + running python -m SimpleHTTPServer 8877

➜ ~ disown %1

➜ ~ jobs

➜ ~

可以看到进程ID 20815前面有一个数字,加一个%即可

说明:这个命令是对作业(job)的操作,所以呢,首先你得把它变成job,很简单,如果你在运行前命令后面加了& 那恭喜你,现在他就是一个job,如果没有呢,也不要急,按下Ctrl+z 就可以把它挂到后台,成为一个job,此时我们可以通过jobs命令来查看所有的job。

关于job还有一些操作,bg %n是将job后台运行,fg %n是将job拿到前台运行,kill %n是杀掉这个job

需要注意的是,当使用过 disown 之后,会将把目标作业从作业列表中移除,我们将不能再使用jobs来查看它,但是依然能够用ps -ef查找到它。

不知道什么反正很吊派

screen 提供了 ANSI/VT100 的终端模拟器,使它能够在一个真实终端下运行多个全屏的伪终端。

screen

建立一个新session

screen

列出所有session

screen -ls

重新连接指定session

screen -r screen_pid

用快捷键CTRL + ad 来暂时断开当前session,CTRL + d 结束当前session。

示例:

➜ ~ screen

(此时跳转到新窗口,按Ctrl+ad暂时断开)

➜ ~ screen -ls

There is a screen on:

31665.pts-37.MBP (2017年08月30日 10时59分49秒) (Attached)

1 Socket in /var/run/screen/S-moma.

➜ ~ screen -r 31665

(恢复到screen_pid为31665的session)

➜ ~ ping google.com &

[1] 2184

(Ctrl+ad离开此session,然后查看进程树)

➜ ~ pstree -H 2184

systemd─┬─ModemManager─┬─{gdbus}

│ └─{gmain}

├─NetworkManager─┬─dhclient

│ ├─dnsmasq

│ ├─{gdbus}

...

├─rtkit-daemon───2*[{rtkit-daemon}]

├─screen───zsh───ping

├─sshd───sshd───sshd───zsh─┬─pstree

│ └─3*[python]

├─2*[systemd───(sd-pam)]

...

(此时我们再连接回刚刚的session可以看到还是在运行的)

说明:

1.通过上面的进程树,我们可以很容易观察到,screen───zsh───ping是直接挂在systemd下的,这也就是不会受SIGHUP信号影响的原因,这跟setsid的原理是一样的,前文提到是init进程实在Linux下的,当前是systemd是因为在实在Mac系统下操作的。

2.还有就是这个命令如果机器上没有的话需要安装,Ubuntu的话是sudo apt-get install screen

3.这个命令是十分强大的,这里只是简单介绍,还有很多神奇的操作,想要玩爽还得自己用man screen去看

参考和引用:

Linux 后台运行

我们常常会用终端连接Linux服务器,然后在运行类似Tomcat 、Web Logic等 web容器的时候希望退出终端依然可以运行。

我们可以通过 nohup command & 来使程序后台运

以Tomcat为例nohup ./startup.sh &

然后在shell中提示了nohup成功后:

nohup: ignoring input and appending output to ‘nohup.out’

然后按键盘任意键,回到shell输入命令窗口,然后在shell中输入

exit

退出终端,这时候,你的Tomcat就作为后台服务挂在Linux上了。

注意:不要执行完nohup直接点击关闭程序关闭终端,这样会干掉该命令的session,导致nohup对应的进程被通知一起被干掉,从而导致后台运行失败。

上文提到过nohup成功后的提示:nohup: ignoring input and appending output to ‘nohup.out’

默认情况下nohup的作业的所有输出会被重定向到 nohup.out这个文件中,当然,你也可以指定输出:

nohup command > vienout.txt 2>&1 &

由于使用nohup时,会自动将输出写入nohup.out文件中,如果文件很大的话,nohup.out就会不停的增大,我们可以利用Linux下一个特殊的文件/dev/null来解决这个问题,这个文件就相当于一个黑洞,任何输出到这个文件的东西都将消失

只保留输出错误信息 nohup command >/dev/null 2>log &

所有信息都不要 nohup command >/dev/null 2>&1 &

这里解释一下后面的2>&1 。 这涉及到Linux的重定向,其中0、1、2分别是标准输入、标准输出、标准错误输出,用来指定需要重定向的标准输入输出。默认情况下是标出输出,也就是1 。例如我们而上文提到的 2>&1 是 将错误信息重定向到标准输出。

还有就是如果不想让程序输出,Linux下有一个/dev/null的特殊文件,就像一个黑洞,所有输出到这个文件的信息全部会消失,如果你不需要输出日志,这样做就不会导致输出日志文件越来越大,占用存储空间的问题了

关于Linux,新手想继续了解一些知识的话,推荐看一下《鸟哥的Linux私房菜》,讲的简单易懂,适合入门和作为工具书平时查阅

附:

ctrl+c #结束当前任务

ctrl+z #挂起当前任务

jobs -l #查看任务,返回任务编号 和 进程号

bg %n #编号n的任务转向后台运行,实际上bg n 也可以

fg %n #编号n的任务转向前台运行

转载请注明来源:

viencoding.com版权所有,允许转载,但转载请注明出处和原文链接: https://viencoding.com/article/6

欢迎小伙伴们在下方评论区留言 ~ O(∩_∩)O

linux断开会话不中断进程,Linux让进程后台运行且连接断开不影响(nohup、setsid、disown、screen)...相关推荐

  1. linux进程后台运行的几种方法 - nohup/setsid//disown/screen

    我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败.如何让命令提交后不受本地关闭终端窗口/网络断开 ...

  2. Linux运行与控制后台进程的方法:nohup, setsid, , disown, screen

    我们经常会碰到这样的问题,用ssh登录了远程的Linux服务器,运行了一些耗时较长的任务,结果却由于网络等的不稳定导致任务中途失败. 这是由于在用户注销(logout)或者网络断开时,终端会收到 HU ...

  3. Linux 将进程放入后台执行,解决网络,ssh断开导致进程结束(nohup, setsid, , disown)...

    Linux 将进程放入后台执行,解决网络,ssh断开导致进程结束(nohup,  setsid,  &, disown) 1.nohup 命令 我们知道,当用户注销(logout)或者网络断开 ...

  4. linux scp 跨服务器,scp跨服务器拷贝,后台运行

    [转载]原文:https://blog.csdn.net/u013091013/article/details/68941250 通常情况下,我门在同一台服务器拷贝数据最常用的命令便是cp,如果要在不 ...

  5. linux下如何部署本jar包并且在后台运行

    执行jar包的命令和在windows操作系统上没有任何区别: 1 先找到自己jar包放在的绝对路径 2 java -jar 跟你jar的绝对路径 3 将jar程序设置成后台运行,并且将标准输出的日志重 ...

  6. Linux忘记将任务放后台 不能终止程序 将前台任务放在后台继续运行 (nohup, setsid, , disown)

    本文链接:https://blog.csdn.net/weixin_40015791/article/details/103621927 今天将任务在服务器跑上,但是忘记放后台了,运行了七八个小时又不 ...

  7. 让进程在后台可靠运行的几种方法 nohup,setsid,,disown,CTRL-z ,screen

    让进程在后台可靠运行的几种方法 几年前在developerWorks上面看到的文章,感觉非常实用,又简单整理了一下,转到这里,希望给看到的人带来一些帮助.文中提到的nohup和subshell方式一直 ...

  8. linux断开会话不中断进程,Linux screen 解决会话终止当前进程断开的问题

    使用原因: 远程到服务器,经常运行一些需要很长时间才能完成的任务,比如备份数据,传输数据等.通常情况下我们都是为每一个这样的任务开一个远程终端窗口,因为它们执行的时间太长了.必须等待它们执行完毕,在此 ...

  9. linux块设备驱动中断程序,linux设备驱动归纳总结(六):1.中断的实现

    linux设备驱动归纳总结(六):1.中断的实现 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

最新文章

  1. 第十八课 色彩样式与滤镜
  2. VTK:模型之FinanceFieldData
  3. java toast_Android中Toast的用法简介
  4. wincc服务器系统,什么情况下用wincc服务器与客户端
  5. imx6q 开发android,SAIL-IMX6Q ANDROID开发环境搭建与系统编译
  6. strcpy()、memcpy()、memmove()、memset()及其应用
  7. Jmeter如何将返回值作为下一接口的参数?
  8. java.lang.UnsatisfiedLinkError: JNA support (com/sun/jna/android-arm/libjnidispatch.so) not found
  9. DDZY719-Z型单相费控智能电能表通过Rola模块实现的无线抄表实验
  10. Adobe Flash Player不是最新版本,导致视频无法播放?
  11. ps两张图片合在一起
  12. 计算机共享在哪里找,电脑共享文件在哪里找
  13. 【C语言】数组和函数
  14. 【程序设计训练】1-7 F1方程式冠军
  15. python程序设计与案例教程王小银_《Python程序设计与案例教程》王小银著【摘要 书评 在线阅读】-苏宁易购图书...
  16. Unity_回合制战斗系统_01
  17. 雷军2001年去搜狐见张朝阳不是为面试 而是给卓越网拉融资
  18. 麻将番型计算(二人麻将)
  19. javaScript:结合mousedown、mousemove、mouseup事件,实现拖动方块在页面内移动(代码)
  20. 内核中的互斥锁的使用

热门文章

  1. 用VScode 插件做代码同步演示,原来实时信令控制还能这么玩
  2. 视频教程-从零学习selenium2(WebDriver)自动化测试系列视频课程-软件测试
  3. 校园广播流程(硬件接口、采集卡设置、)
  4. pil版本下载linux,linux 安装 pil
  5. 【html】点击图片内链接进行跳转
  6. MySQL - 关于 False、True、0、1、tinyint(1) 的说明
  7. Java遍历Map和List及嵌套使用
  8. Linux下反弹shell
  9. window反弹shell
  10. ppt转换成word的几种方法