我们经常会碰到这样的问题,用 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. 搜索法 | 1103 dfs搜索:符合条件的多项式

    其实这题我已经写过两遍了,但都是在看过算法笔记的情况下写的.方法不难,只要能想出来. 找到一个项数为k,每项为p次幂,和为n,并且在有多个结果的情况下要求数字之和最大的一个多项式.如果数字之和相等.还 ...

  2. bzoj2839 集合计数 组合计数 容斥原理|题解

    集合计数 题目描述 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使得它们的交集的元素个数为K,求取法的方案数,答案模1000000007.(是 ...

  3. 基于 SpringBoot2.0+优雅整合 SpringBoot+Mybatis

    SpringBoot 整合 Mybatis 有两种常用的方式,一种就是我们常见的 xml 的方式 ,还有一种是全注解的方式.我觉得这两者没有谁比谁好,在 SQL 语句不太长的情况下,我觉得全注解的方式 ...

  4. concurrent(七)ConcurrentHashMap源码分析

    参考文档:https://www.cnblogs.com/xiaoxi/p/7474026.html https://www.ibm.com/developerworks/cn/java/java-l ...

  5. Isilon的WebUI上指定跨时区时间的小问题

    Isilon的WebUI的界面长这样: 假设我们在中国,也就是GMT+8的时区,我们想修改一个远在美国的Isilon cluster的时间. 你会发现,界面上用于指定时间的地方应该填写的不是下面选择的 ...

  6. python selenium爬虫工具

    今天seo的同事需要一个简单的爬虫工具, 根据一个url地址,抓取改页面的a连接,然后进入a连接里面的页面再次抓取a连接 1.需要一个全局的set([])集合来保存抓取的url地址 2.由于现在单页面 ...

  7. 『摆渡车 斜率优化dp及总结』

    摆渡车的题解我已经写过一遍了,在这里,这次主要从斜率优化的角度讲一下摆渡车,并总结一下斜率优化会出现的一些奇奇怪怪的错误. 摆渡车 Description 有 n 名同学要乘坐摆渡车从人大附中前往人民 ...

  8. 简明 Java 错误处理机制

    用个最简单的例子来展示为什么需要错误处理,以及怎么用. import java.io.FileInputStream; import java.io.FileNotFoundException; pu ...

  9. ubuntu开机自动挂载硬盘

    1. 查看硬盘信息 df -h 命令找到目标硬盘(可根据 磁盘分区(路径).分区大小.挂载点  确认/定位 目标) sudo blkid 命令找到目标硬盘的UUID,(关注一下分区的格式化类型,如ex ...

  10. MySQL卸载与重装

    [卸载] 不推荐使用控制面板-->卸载程序,来卸载,容易出现报错. 使用电脑管家卸载很轻松. [删除注册列表] HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\S ...