我们经常会碰到这样的问题,用 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. dfs的两种处理方法

    方法一: 对于源点s,初始化vis[s]=1,并且在dfs之后vis[s]=1,为下一次调用做准备 .对于dfs递归中的寻找后继的循环体,入栈出栈语句写在循环内. 模板: //调用 vis[s]=; ...

  2. A 题解————2019.10.16

    [题目描述] 对于给定的一个正整数n, 判断n是否能分成若干个正整数之和 (可以重复) ,其中每个正整数都能表示成两个质数乘积. [输入描述]第一行一个正整数 q,表示询问组数.接下来 q 行,每行一 ...

  3. 4.28(TG模拟赛)总结

    1.挖地雷 题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N≤20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之后,某人可以从任 ...

  4. 【树形DP】【P3177】[HAOI2015] 树上染色

    Description 给定一棵 \(n\) 个点的带权树,要求选 \(k\) 个点染成黑色,剩下染成白色,最大化两两同色点之间的距离和. Limitations \(0 \leq k \leq n ...

  5. js中的自动包装机制

    有一行语句: 1.toString() //error 那么问题来了,为什么报错? 我的第一想法就是1是一个基本类型,所以它没有toString方法 嗯,理直气壮 接下来有大佬show me code ...

  6. awesome-RecSys

    https://github.com/jihoo-kim/awesome-RecSys?fbclid=IwAR1m6OebmqO9mfLV1ta4OTihQc9Phw8WNS4zdr5IeT1X1OL ...

  7. java 执行 shell脚本通过mysql load data导入数据

    1:load_data_test.sh #!/bin/sh load_data_log=/mnt/load_data_test/load.log load_sql="LOAD DATA LO ...

  8. Spring JDBC最佳实践(3)

    原文地址:https://my.oschina.net/u/218421/blog/38598 spring jdbc包提供了JdbcTemplate和它的两个兄弟SimpleJdbcTemplate ...

  9. Win10创建mysql8.0桌面快捷方式以及启动mysql.exe闪退问题

    1.先找到mysql的bin目录,将Mysql.exe发送快捷方式到桌面. 2.然后右键选择属性,将目标后面添加上 -uroot -p 我的完整目标如下: E:\mysql-8.0.17-winx64 ...

  10. 从有序矩阵M x N中找出是否包含某一个数,要求时间复杂度为O(M+N)

    有序指的是每行从左到右依次变大,每列从上到下依次变大 思路: 从右上顶点开始依次判断当前值与给定值的大小,往左下顶点移动,结束条件是下标超过范围 public class FindNumInOrder ...