我们经常会碰到这样的问题,用 telnet/ssh 登录了远程的 Linux 服务器,运行了一些耗时较长的任务, 结果却由于网络的不稳定导致任务中途失败。

解决办法:

当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程。因此,我们的解决办法就有两种:要么让进程忽略 HUP 信号,要么让进程运行在新的会话里从而成为不属于此终端的子进程。



模拟一个断开的会话,看一下前台进程是否还会正常运行:

[root@node1 ~]# cat b.sh
#!/bin/bash
for((;;)) do
sleep 1
echo "no" >> /tmp/b.txt
done 第一个会话:
[root@node1 ~]# bash b.sh #执行脚本,会占据整个当前会话页面 新打开一个会话:
[root@node1 ~]# ps -ef | grep b.sh
root 34693 28170 0 11:32 pts/0 00:00:00 bash b.sh
...
[root@node1 ~]# kill -1 34693 #模拟第一个会话断开的情况,发送SIGHUP信号 再次切换至第一个会话:
[root@node1 ~]# bash b.sh
Hangup #已经断线
[root@node1 ~]#

nohup

nohup - run a command immune to hangups, with output to a non-tty

运行一个忽略hangups(SIGHUP)影响的命令,输出到一个非tty

格式:

nohup COMMAND [ARG]...

示例:

[root@node1 ~]# nohup bash b.sh          #占据当前会话,使得当前会话不可执行其它命令
nohup: ignoring input and appending output to ‘nohup.out’ #如不指定日志输出位置,默认输出至当前目录下的nohup.out文件中。 重新打开一个会话:
[root@node1 ~]# ps -ef | grep b.sh
root 25973 16490 0 09:56 pts/1 00:00:00 bash b.sh
[root@node1 ~]# kill -1 25973 #向进程发送SIGHUP信号,nohup进程还在运行。关闭上一个session会话,效果和kill -1效果一样
[root@node1 ~]#

nohup将标准输出和标准错误缺省会被重定向到nohup.out文件中。一般我们可在结尾加上&来将命令同时放入后台运行,也可用>xxx.log 2>&1(将标准输出和标准错误输出至指定的文件中)来更改缺省的重定向文件名。

setsid

setsid - run a program in a new session

在一个新的会话中运行一个程序。

格式:

setsid program [arg...]

示例:

[root@node1 ~]# setsid bash b.sh      #使用setsid来代替nohup
[root@node1 ~]# jobs #后台无法查看
[root@node1 ~]# ps -ef | grep c.sh #ps查找其进程,可以看到PID是43019,但PPID确为1(systemd)
root 43593 1 0 14:15 ? 00:00:00 bash b.sh
root 44473 43385 0 14:22 pts/1 00:00:00 grep --color=auto b.sh [root@node1 ~]# pstree -H 43593 -p
systemd(1)─┬─NetworkManager(3403)─┬─{NetworkManager}(3543)
│ └─{NetworkManager}(3551)
├─agetty(3528)
├─auditd(2802)───{auditd}(2806)
├─bash(43593)───sleep(44564) #因为父进程是1,不属于某个终端的子进程,所以也就无法接收到HUP信号。但是不能使用专门指定这个此进程发送HUP信号,这样是会中断的。
├─chronyd(3472)
├─crond(3490)
...
├─sshd(4154)───sshd(16488)─┬─bash(36542)───less(40656)
│ ├─bash(42726)
│ └─bash(43385)───pstree(44565)
...

同样的,在shell也有一种可以使用进程的PPID改成1的方法,使用`()`括起来并加上`&`,也和`setsid`效果一样。
```
[root@node1 ~]# (bash b.sh &) #后台执行命令
[root@node1 ~]# jobs #jobs无法查看
[root@node1 ~]# ps -ef | grep b.sh
root 45631 1 0 14:30 pts/1 00:00:00 bash b.sh #PPID为1
root 45706 43385 0 14:31 pts/1 00:00:00 grep --color=auto b.sh
[root@node1 ~]# kill -1 45631 #向进程发送HUP信号
[root@node1 ~]# ps -ef | grep b.sh #进程被中断
root 45784 43385 0 14:31 pts/1 00:00:00 grep --color=auto b.sh
[root@node1 ~]#


<br /> ##jobs:
> 显示当前会话下后台任务列表。也就是说,如果当命令切换至后台和想要显示后台有哪些进程不是同一个会话,那么将查不出来有哪些后台进程。 **格式:**
`jobs [option]` **常用选项:**
* -l:列出进程ID及其它信息
* -p:仅列出PID
* -n:仅列出自从上次输出了状态变化提示。run -> stop
* -r:显示运行中的进程
* -s:显示停止的进程 <br />
##fg:
> 将命令从后台作业提到前台终端运行。使用格式`fg 任务号`。任务号是由jobs命令获取的第一列。 <br /> ##bg:
> 使用格式`bg 任务号`。想要使用bg命令,首先对前台命令`ctrl+z`下放置后台成stop模式后,在对其使用bg命令才能像一开始在命令后添加`&`一样后台运行。需要注意的是,如果挂起会影响到当前进程执行的结果,请慎用`ctrl+z`在`bg`。 <br /> **示例:**

[root@node1 ~]# bash b.sh #ctrl+z挂起进程至后台

^Z

[1]+ Stopped bash b.sh

[root@node1 ~]# jobs

[1]+ Stopped bash b.sh

[root@node1 ~]# bg 1 #后台继续运行

[1]+ bash b.sh &

[root@node1 ~]# jobs #已经运行

[1]+ Running bash b.sh &

[root@node1 ~]#

[root@node1 ~]# bash #重新打开一个bash

[root@node1 ~]# jobs #查询后台进程,查询为空,所以jobs只能查询当前会话的后台进程。

[root@node1 ~]#

[root@node1 ~]# exit #退出新的bash

exit

[root@node1 ~]# jobs #查看jobs

[1]+ Running bash b.sh &

[root@node1 ~]# fg 1 #调至前台运行

bash b.sh


<br /> **总结:**
`nohup`是使用进程本身忽略HUP信号从而达到可以后台运行不被意外中断。`setsid`和shell中的`( &)`是将进程的父进程改为1,从而达到不受sshd连接的各种情况影响。
`jobs`,`bg`,`fg`三个命令只能在当前的会话终端上执行,一但会话终端意外剥离,就无法在操作。
<br /> 参考资料:[https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/index.html](https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/index.html)

nohup-长期运行进程的更多相关文章

  1. nohup 让进程在后台可靠运行的几种方法

    1. nohup nohup 无疑是我们首先想到的办法.顾名思义,nohup 的用途就是让提交的命令忽略 hangup 信号. nohup 的使用是十分方便的,只需在要处理的命令前加上 nohup 即 ...

  2. Shell: nohup守护进程化

    如果想在终端会话中启动shell脚本,然后让脚本一直以后台模式运行,直到其完成,即使你退出了终端会话,可以使用nohup命令实现.感觉nohup就是将一个进程初始化为一个守护进程. nohup命令运行 ...

  3. Linux:使用nohup让进程在后台可靠运行

    学习之余我最大的乐趣是找一部不错的电影慢慢品味,这也是我缓解压力的最好方式之一,由于我常去的字幕组网站需要签到才可以下载字幕,像这种娱乐网站谁有时间天天记得去签到呢,but作为一个准程序猿应该有更好的 ...

  4. nohup程序后台执行

    Linux常用命令,用于不挂断的执行程序. nohup命令:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用nohup命令.该命令可以在你退出帐户/关闭终端之后继续运行相应 ...

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

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

  6. U盘安装CentOS系统、raid5制作以及nohup的使用

    最近折腾服务器,用U盘安装了系统,总结了一些避坑措施: 下载UltraISO工具,用来刻盘 从centos官网下载ISO镜像,然后刻盘 关键是在你进入系统安装界面后,如下: 选中第一项,按tab键(看 ...

  7. Linux——进程管理学习简单笔记

    基本概念: 进程和程序的区别 : 1.程序是静态概念,本身作为一种软件资源长期保存:而进程是程序的执行过程,它是动态概念,有一定的生命期,是动态产生和消亡的. 2.程序和进程无一一对应关系.一个程序可 ...

  8. Linux学习笔记(2)linux系统信息与进程相关命令

    man 获得命令的帮助手册,如man cp:按q键退出 su 切换用户,如su - root; '-'表示改变用户的环境变量 who 显示系统中登录的用户 w 显示登录用户的详细信息 last 查看最 ...

  9. Linux用户登出之后保持后台进程(nohup)

    使用&可以将进程置于后台,但是用户从Shell登出之后,进程会自动结束.想要在登出之后保持进程运行,就要结合nohup命令使用. 例如: nohup find -size +100k > ...

  10. Linux后台执行脚本 &与nohup

    Linux后台执行脚本的方式: 0.脚本代码 [root@VM_1_3_centos apps]# cat test.php <?php sleep(5); echo "hello w ...

随机推荐

  1. CF1276 D. Tree Elimination

    CF1276 D. Tree Elimination 传送门 CodeForces Solution 考虑树型\(dp\),设\(f_{u,0/1/2/3}\)分别表示点\(u\)被自己父亲边之前的边 ...

  2. Android 10 终于来了!增加了不少新特性

    前言 Android 10 正式发布了,根据官网的介绍,聚焦于隐私可控.手机自定义与使用效率,此版本主要带来了十大新特性:   image 智能回复 使用机器学习来预测你在回复信息时可能会说些什么,这 ...

  3. 2019-2020-1 20181218《Linux内核原理与分析》第一周作业

    目录 问题和参考 有趣/有用的Linux命令 小作业和解答 一些图片 相关学习 本文是学习Linux基础入门(新版)后的总结. 问题和参考 虚拟机莫名崩溃,一天重启了几十次电脑,重装两次系统,心累.想 ...

  4. 【操作系统之六】Linux常用命令之less

    一.概念less 工具也是对文件或其它输出进行分页显示的工具,是linux正统查看文件内容的工具,功能极其强大.less 的用法比起 more .tail更加的有弹性.在 more 的时候,我们并没有 ...

  5. cad.net 读取pc3,pmp 读取pc3打印机文件

    修改pc3文件还没做好..大家先look look怎么读.... 首先弄一个控制台程序, 然后去下载 Ionic.Zip 这个东西...载到控制台...都很简单... 然后就是复制下面代码,看控制台显 ...

  6. Python 的 Pandas 对矩阵的行进行求和

    Python 的 Pandas 对矩阵的行进行求和: 若使用 df.apply(sum) 方法的话,只能对矩阵的列进行求和,要对矩阵的行求和,可以先将矩阵转置,然后应用 df.apply(sum) 即 ...

  7. python 在cmd时执行celery -A tasks worker --loglevel=info报错:failed to create process怎么解决

    在cmd命令前加 : python -m 命令(如:python -m celery -A tasks worker --loglevel=info) -m: 将库中的python模块用作脚本去运行, ...

  8. php中命名空间namespace和use

    对于面向对象编程而言,命名空间namespace和use的概念非常重要. 1.根命名空间是反斜线 \ ,有点类似linux中的根目录 / 的那种感觉,但使用var_dump()函数打印时其实是空字符串 ...

  9. 搭建zipkin并以mysql的方式存储数据

    zipkin以mysql的方式存储 (centos+java8+mysql+zipkin2.3.1) 前言: 这篇教程用于搭建已mysql作为存储的zipkin.(还不知道zipkin是什么的小伙伴请 ...

  10. NOI2019网络同步赛游记

    我发的邮件**f没收到,后来去专门询问才整到一个名额(估计是嫌我太菜,参加了也是垫底) day -1 上午写了到类似随机游走的高斯消元期望dp,然后颓颓颓 下午打洛咕月赛.T1一直50pts,后来才知 ...