我们经常会碰到这样的问题,用 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. async和await对promise异步方案的改进,以及使用注意事项

    async.await相比原生promise的有优势: 1.更加简洁,await一个promise即可,那么会自动返回这个promise的resolve值,无需在then函数的回调中手动取值,彻底解决 ...

  2. 洛谷P5021 赛道修建

    题目 首先考虑二分,然后发现最小长度越大的话,赛道就越少.所以可以用最终的赛道个数来判断长度是否合理.问题转化为给定一个长度,问最多有多少条互不重叠路径比这个给定长度大. 考虑贪心,毕竟贪心也是二分c ...

  3. [题解向] [Luogu1441] 砝码称重

    \(\color{red}{\mathcal{Description}}\) \(Link\) \(\color{red}{\mathcal{Solution}}\) 思路:\(01\)背包方案数 + ...

  4. 从最近的比赛学习CTR/CVR

    https://zhuanlan.zhihu.com/p/35046241 包大人 深度学习炼丹劝退师 278 人赞同了该文章 从最近的比赛学习CTR/CVR 最近在玩kaggle的talking d ...

  5. shell脚本监控k8s集群job状态,若出现error通过触发阿里云的进程监控报警

    #!/bin/bash while [ 1 ] do job_error_no=`kubectl get pod -n weifeng |grep -i "job"|grep -c ...

  6. Apache Beam实战指南 | 大数据管道(pipeline)设计及实践

    Apache Beam实战指南 | 大数据管道(pipeline)设计及实践  mp.weixin.qq.com 策划 & 审校 | Natalie作者 | 张海涛编辑 | LindaAI 前 ...

  7. char[],char *,string之间转换

    char []与char *之间转换 char []转char *:直接进行赋值即可 // char[] 转char *char str[] = "lala";char *str1 ...

  8. 啊哈!算法(第一章)C#实现

    第1节 最简单的排序--桶排序     期末考试完了老师要将同学们的分数按照从高到低排序. 小哼的班上只有 5 个同学,这 5 个同学分别考了 5 分.3 分.5 分.2 分和 8 分,考得真是惨不忍 ...

  9. [SOJ #696]染色(2019-11-10考试)/[Atcoder MUJIN Programming Challenge C]Orange Graph

    题目大意 有一个\(n\)个点\(m\)条边的简单无向连通图,初始为白色,可以执行操作让一些边变黑,要求使得操作后的图不存在黑色的奇环,且不能使得其他的任何变黑而还符合要求.问最后有多少可能结果.\( ...

  10. Java学习:抽象方法和抽象类的使用

    抽象 抽象方法:就是加上abstract关键字,然后去掉大括,直接分号结束.抽象类:抽象方法所在的类,必须是抽象类才行.在class之前写上abstract即可. 如何使用抽象类和抽象方法: 1.不能 ...