zoukankan      html  css  js  c++  java
  • Linux :忘记使用nohup该如何补救

    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程序依然执行

  • 相关阅读:
    Python使用SMTP模块、email模块发送邮件
    harbor搭建及使用
    ELK搭建-windows
    ELK技术栈之-Logstash详解
    【leetcode】1078. Occurrences After Bigram
    【leetcode】1073. Adding Two Negabinary Numbers
    【leetcode】1071. Greatest Common Divisor of Strings
    【leetcode】449. Serialize and Deserialize BST
    【leetcode】1039. Minimum Score Triangulation of Polygon
    【leetcode】486. Predict the Winner
  • 原文地址:https://www.cnblogs.com/rossiXYZ/p/14826420.html
Copyright © 2011-2022 走看看