Linux :忘记使用nohup该如何补救

0x00 摘要

在Linux做开发的同学也许会遇到这种困境:

  1. 运行了一个程序两个小时之后,你心想:再有一个小时程序就运行完了,于是你兴致勃勃的准备看结果。
  2. 女朋友突然发飙让自己立刻出现。
  3. 此时你突然发现自己没有使用 nohup,这就意味着这个程序在自己离开之后会死掉。之前两个小时的运行时间就浪费了。
  4. 于是你满怀悔恨的按下了CTR+c,然后使用 nohup 重新运行程序。

慢着,其实这种忘记 nohup 的情况是可以补救的,下面我们就看看如何操作。

0x01 问题描述

1.1 为何关闭进程

当用户注销(logout)或者网络断开时,终端会收到 HUP(hangup)信号从而关闭其所有子进程

原因是:SSH会话关闭时,ssh所关联的pty关闭,系统会给这个pty所关联的session中的所有进程发送SIGHUP信号,SIGHUP的默认信号处理程序是终止进程,除非进程自己处理了SIGHUP。

因此,我们的解决办法就有两种途径:

  • 要么让进程忽略 HUP 信号;
  • 要么让进程运行在新的会话里从而成为不属于此终端的子进程;

1.2 nohup 作用

nohup命令对进程做了三件事。

  • 阻止SIGHUP信号发到这个进程。
  • 关闭标准输入。该进程不再能够接收任何输入,即使运行在前台。
  • 重定向标准输出和标准错误到文件nohup.out

也就是说,nohup命令实际上将子进程与它所在的 session 分离了。所以当shell窗口关闭时候,nohup 命令所在的进程也不会被结束。

0x02 简述

如果忘记使用了 nohup,该如何补救?具体操作如下:

2.1 操作序列

具体操作序列如下:

  1. 对于正在运行的进程,我们可以使用 ”CTRL+ z“ 来将当前进程挂起到后台暂停运行;
  2. 这时候进程已经进入后台暂停,我们使用 "jobs" 找到之前暂停的进程,每一个后台任务具有一个 jobnumber(任务的序列号,非PID)。
  3. 使用 "bg jobnumber" 让该进程进入后台运行;
  4. 再次使用 "jobs"查看进程状态,此时进程已经进入running 状态;
  5. 使用disown命令 "disown -h %jobnumber" 进行处理,这样该进程就会起到了 nohup 的同样作用;此时大功告成。
  6. 如果想继续查看,可以使用 ps 命令来查看进程状态;
  7. 可以使用 "fg" 把后台任务转成前台任务运行,此时可以对该进程进行操作,比如结束;

2.2 样例

我们以运行一个redis为例给出具体操作序列,具体如下图:

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server
mylinux $ jobs
[1]+ Stopped redis-server
mylinux $ bg 1
[1]+ redis-server &
mylinux $ jobs
[1]+ Running redis-server &
mylinux $ disown -h %1
mylinux $ ps -elf| grep redis
501 1987 521 4006 0 31 0 4289624 1932 - T 0 ttys001 0:00.01 redis-server *:6 9:49上午
mylinux $ fg
redis-server
^C1987:signal-handler (1616291836) Received SIGINT scheduling shutdown...
1987:M 21 Mar 09:57:16.634 # User requested shutdown...
1987:M 21 Mar 09:57:16.634 * Saving the final RDB snapshot before exiting.
1987:M 21 Mar 09:57:16.641 * DB saved on disk
1987:M 21 Mar 09:57:16.641 # Redis is now ready to exit, bye bye...

0x03 原理

下面我们对操作命令的原理一一进行分析。

3.1 CTRL + Z

Ctrl+Z是把当前的程序挂起,暂停执行这个程序。

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server

这样程序就被挂起进入了后台。可以挂起好多进程到后台。

3.2 jobs

jobs命令用来查看当前有多少在后台运行。

在Linux中,启动、停止、终止以及恢复作业的这些功能统称为作业控制。作业控制中的关键命令是jobs命令,jobs命令允许查看shell当前正在处理的作业。jobs命令中输出有加号和减号,带加号的作业被当做默认作业,带减号的为下一个默认作业。

一旦当前的默认工作处理完成,则带减号的工作就会自动成为新的默认工作,换句话说,不管此时有多少正在运行的工作,任何时间都会有且仅有一个带加号的工作和一个带减号的工作。

我们可以看到,此时 redis-server 就在后台运行,[1] 表示进程编号为 1。

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server
mylinux $ jobs
[1]+ Stopped redis-server

3.3 bg

bg命令能够将在后台暂停的命令,变为在后台进行继续执行。

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server
mylinux $ jobs
[1]+ Stopped redis-server
mylinux $ bg 1
[1]+ redis-server &

使用了bg之后,可以看到输出 redis-server 之后带了一个 &,表示已经后台运行。

我们也可以再次使用 jobs 查看进程状态。

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server
mylinux $ jobs
[1]+ Stopped redis-server
mylinux $ bg 1
[1]+ redis-server &
mylinux $ jobs
[1]+ Running redis-server &

3.4 disown

disown 命令 可以将指定任务从"后台任务"列表(jobs命令的返回结果)之中移除。一个"后台任务"只要不在这个列表之中,session 就肯定不会向它发出SIGHUP信号。这样就达到了 nohup 相同的作用。

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server
mylinux $ jobs
[1]+ Stopped redis-server
mylinux $ bg 1
[1]+ redis-server &
mylinux $ jobs
[1]+ Running redis-server &
mylinux $ disown -h %1

3.5 ps

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

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server
mylinux $ jobs
[1]+ Stopped redis-server
mylinux $ bg 1
[1]+ redis-server &
mylinux $ jobs
[1]+ Running redis-server &
mylinux $ disown -h %1
mylinux $ ps -elf| grep redis
501 1987 521 4006 0 31 0 4289624 1932 - T 0 ttys001 0:00.01 redis-server *:6 9:49上午

3.6 fg

fg 命令能够将在后台运行的命令调至前台进行运行,如果后台运行的任务数量比较多,可以通过选择jobnumber(任务的序列号,非PID)来进行选择。

另外关于当前任务,如果后台运行的任务号有2个时候,当1号任务执行完毕之后,2号任务此时就为当前任务,那么使用fg、bg等命令不加上job number的时候,默认为变动的都是当前任务。

mylinux $ redis-server
* The server is now ready to accept connections on port 6379
^Z
[1]+ Stopped redis-server
mylinux $ jobs
[1]+ Stopped redis-server
mylinux $ bg 1
[1]+ redis-server &
mylinux $ jobs
[1]+ Running redis-server &
mylinux $ disown -h %1
mylinux $ ps -elf| grep redis
501 1987 521 4006 0 31 0 4289624 1932 - T 0 ttys001 0:00.01 redis-server *:6 9:49上午
mylinux $ fg
redis-server

0xEE 个人信息

★★★★★★关于生活和技术的思考★★★★★★

微信公众账号:罗西的思考

如果您想及时得到个人撰写文章的消息推送,或者想看看个人推荐的技术资料,敬请关注。

0xFF 参考

https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/

https://www.ibm.com/developerworks/cn/linux/l-cn-screen/

nohup命令_掌握这几个命令,Linux后台任务提交,前后台任务转换随便玩

Linux的jobs命令

Linux jobs命令:查看当前终端放入后台的工作

Linux 守护进程的启动方法

Linux中shell关闭后,nohup让程序依然在后台运行

nohup:关闭shell程序依然执行

Linux :忘记使用nohup该如何补救的更多相关文章

  1. Linux scp 设置nohup后台运行

    Linux scp 设置nohup后台运行 1.正常执行scp命令 2.输入ctrl + z 暂停任务 3.bg将其放入后台 4.disown -h 将这个作业忽略HUP信号 5.测试会话中断,任务继 ...

  2. linux忘记mysql密码找回方法

    linux忘记mysql教程密码找回方法 今天我们主要是讲一下关于linux忘记mysql密码处理方法,下面提供了5种linux忘记mysql密码找回方法哦.    方法一: # /etc/init. ...

  3. 【java】 linux下利用nohup后台运行jar文件包程序

    Linux 运行jar包命令如下: 方式一: java -jar XXX.jar 特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 那如何让窗口不锁定? 方式二 ...

  4. Linux忘记开机密码怎么办?

    Linux忘记开机密码怎么办?1. 开机ESC/Shift,在出现grub画面时,用上下键选中你平时启动linux的那一项,然后按e键2. 再次用上下键选中你平时启动linux的那一项(类似于kern ...

  5. Linux下java nohup 后台运行关闭后进程停止的原因,不挂断后台运行命令

    Linux下java nohup 后台运行关闭后进程停止的原因,不挂断后台运行命令 今天写sh脚本发现一终止命令程序就停止运行了,检查了很久才发现后面少了个&字符导致的!错误写法:nohup ...

  6. Linux 忘记密码解决方法,Linux 远程登录

    一.Linux 忘记密码解决方法 很多朋友经常会忘记Linux系统的root密码,linux系统忘记root密码的情况该怎么办呢?重新安装系统吗?当然不用!进入单用户模式更改一下root密码即可. 步 ...

  7. openSUSE Linux 忘记root密码的解决方法

    openSUSE Linux 忘记root密码的解决方法 : 对于大部分linux发行版本,忘记root密码的时候,是可以通过单用户模式来重设密码的. 如在redhat/fedora 下,可以通过在启 ...

  8. 【Linux学习】nohup后台运行程序以及输出重定向

    Linux有两种命令使程序后台运行 第一种:支持后台运行,但是关闭终端的话,程序也会停止 command & 第二种:支持后台运行,关闭终端后,程序也会继续运行 nohup command & ...

  9. Linux 忘记密码怎么办

    Linux 忘记密码解决方法 很多朋友经常会忘记Linux系统的root密码,linux系统忘记root密码的情况该怎么办呢?重新安装系统吗?当然不用!进入单用户模式更改一下root密码即可. 步骤如 ...

随机推荐

  1. Jmeter(四十三) - 从入门到精通高级篇 - Jmeter之IP伪装和欺骗(详解教程)

    1.简介 我们从小接受的教育就是不要撒谎,要做一个诚实的孩子,但是在现实生活中有时候说一个善意的谎言也不是可以的.这里由于服务器各种安全机制的限制和校验,因此我们不得不欺骗一下服务器,今天宏哥就给大家 ...

  2. poj_3617 解题

    题意: 给定长度为N的字符串S,要构造一个长度为N的字符串T串. 从S的头部删除一个字符,加到T的尾部 从S的尾部删除一个字符,加到T的尾部 目标是构造字典序尽可能小的字符串. 示例输入: ACDBC ...

  3. DVWA之Insecure Captcha

    Insecure CAPTCHA Insecure CAPTCHA,意思是不安全的验证码,CAPTCHA是Completely Automated Public Turing Test to Tell ...

  4. Windows核心编程 第十七章 -内存映射文件(上)

    第1 7章 内存映射文件 对文件进行操作几乎是所有应用程序都必须进行的,并且这常常是人们争论的一个问题.应用程序究竟是应该打开文件,读取文件并关闭文件,还是打开文件,然后使用一种缓冲算法,从文件的各个 ...

  5. 使用 Azure Container Registry 储存镜像

    Azure Container Registry(容器注册表)是基于 Docker Registry 2.0规范的托管专用 Docker 注册表服务. 可以创建和维护 Azure 容器注册表来存储与管 ...

  6. 【DB宝51】CentOS7修改网卡名称

    目录 1.修改/etc/default/grub文件 2.修改/etc/udev/rules.d/70-persistent-net.rules文件 3.修改网卡配置文件 4.重启服务器 需求:原来的 ...

  7. 使用jenkins一键打包发布vue项目

    jenkins的安装 Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件. Jenkins 支持各种运行方式,可通过系统包.Docker 或者通过一个独立 ...

  8. 简述MySQL优化

    数据库的优化可以从四个方面来优化: 1.结构层: web服务器采用负载均衡服务器,mysql服务器采用主从复制,读写分离 2.储存层: 采用合适的存储引擎,采用三范式 3.设计层: 采用分区分表,索引 ...

  9. Govern EventBus - 历经多年生产环境验证的事件驱动架构框架

    Govern EventBus Govern EventBus 是一个历经四年生产环境验证的事件驱动架构框架, 通过事件总线机制来治理微服务间的远程过程调用. 使用本地事务来支持微服务内强一致性,事件 ...

  10. windows下使用dos命令手工与ntp服务器同步系统时间

    管理员模式的命令窗口 net stop w32time &w32tm /unregister &w32tm /register &net start w32time & ...