zoukankan      html  css  js  c++  java
  • Linux命令nohup+screen

    如果想在关闭ssh连接后刚才启动的程序继续运行怎么办,可以使用nohup。但是如果要求第二天来的时候,一开ssh,还能查看到昨天运行的程序的状态,然后继续工作,这时nohup是不行了,需要使用screen来达到这个目的。

    nohup命令可以用来执行其他命令,并且忽略SIGHUP信号(run a command immune to hangups, with output to a non-tty。Run COMMAND, ignoring hangup signals.)当一个虚拟终端的网络连接断开时,操作系统向正在运行的程序发送SIGHUP信号(HUP = HangUP、挂断),默认情况下这个信号将使程序退出。

     
    一 nohup
    问题1为什么ssh一关闭,程序就不再运行了?
    元凶:SIGHUP 信号 
    让我们来看看为什么关掉窗口/断开连接会使得正在运行的程序死掉。
    在Linux/Unix中,有这样几个概念:
    进程组(process group):一个或多个进程的集合,每一个进程组有唯一一个进程组ID,即进程组长进程的ID。
    会话期(session):一个或多个进程组的集合,有唯一一个会话期首进程(session leader)。会话期ID为首进程的ID。
    会话期可以有一个单独的控制终端(controlling terminal)。与控制终端连接的会话期首进程叫做控制进程(controlling process)。当前与终端交互的进程称为前台进程组。其余进程组称为后台进程组。
    根据POSIX.1定义:
    挂断信号(SIGHUP)默认的动作是终止程序。
    当终端接口检测到网络连接断开,将挂断信号发送给控制进程(会话期首进程)。
    如果会话期首进程终止,则该信号发送到该会话期前台进程组。
    一个进程退出导致一个孤儿进程组中产生时,如果任意一个孤儿进程组进程处于STOP状态,发送SIGHUP和SIGCONT信号到该进程组中所有进程。
    结论:因此当网络断开或终端窗口关闭后,也就是SSH断开以后,控制进程收到SIGHUP信号退出,会导致该会话期内其他进程退出。
     
    简而言之:就是ssh 打开以后,bash等都是他的子程序,一旦ssh关闭,系统将所有相关进程杀掉!! 导致一旦ssh关闭,执行中的任务就取消了
     
     
    例子:
    我们来看一个例子。打开两个SSH终端窗口,在其中一个运行top命令。
    [root@tivf09 root]# top
     
    在另一个终端窗口,找到top的进程ID为5180,其父进程ID为5128,即登录shell。
    [root@tivf09 root]# ps -ef|grep top
    root      5180  5128  0 01:03 pts/0    00:00:02 top
    root      5857  3672  0 01:12 pts/2    00:00:00 grep top
     
    使用pstree命令可以更清楚地看到这个关系:
    [root@tivf09 root]# pstree -H 5180|grep top
    |-sshd-+-sshd---bash---top
               
     
    使用ps-xj命令可以看到,登录shell(PID 5128)和top在同一个会话期,shell为会话期首进程,所在进程组PGID为5128,top所在进程组PGID为5180,为前台进程组。
    [root@tivf09 root]# ps -xj|grep 5128
     5126  5128  5128  5128 pts/0     5180 S        0   0:00 -bash
     5128  5180  5180  5128 pts/0     5180 S        0   0:50 top
     3672 18095 18094  3672 pts/2    18094 S        0   0:00 grep 5128
     
    关闭第一个SSH窗口,在另一个窗口中可以看到top也被杀掉了。
    [root@tivf09 root]# ps -ef|grep 5128
    root     18699  3672  0 04:35 pts/2    00:00:00 grep 5128
     
    问题2   为什么守护程序就算ssh 打开的,就算关闭ssh也不会影响其运行? 
    因为他们的程序特殊,比如httpd –k start运行这个以后,他不属于sshd这个进程组  而是单独的进程组,所以就算关闭了ssh,和他也没有任何关系! 
    [root@CentOS5-4 ~]# pstree |grep http
         |-httpd
    [root@CentOS5-4 ~]# pstree |grep top
         |-sshd-+-sshd---bash---top
     
     
    结论:守护进程的启动命令本身就是特殊的,和一般命令不同的,比如mysqld_safe 这样的命令 一旦使用了  就是守护进程运行。所以想把一般程序改造为守护程序是不可能,
     
    问题3 使用后台运行命令&  能否将程序摆脱ssh进程组控制呢  也就是ssh关闭,后台程序继续运行? 
    我们做一个试验:  find / -name ‘*http*’ &
    利用ctrl+d 注销以后 再进入系统  会不会看见这个命令再运行?
    答案是  :命令被中止了!!
     
    因为他依然属于这个ssh进程组 就算加了&也无法摆脱!!
    [root@CentOS5-4 ~]# pstree |grep find
         |-sshd-+-sshd---bash---find
     
    结论就是:只要是ssh 打开执行的一般命令,不是守护程序,无论加不加&,一旦关闭ssh,系统就会用SIGHUP终止
     
    问题4  nohup能解决的问题
    但是为了能够再注销以后 依然能后台运行,那么我们就可以使用nohup这个命令,我们现在开始查找find / -name ‘*http*’ &
    ,并且希望在后台运行,
    那么就使用nohup:nohup find / -name "*httpd*"
    此时默认地程序运行的输出信息放到当前文件夹的 nohup.out 文件中去
    加不加&并不会影响这个命令   只是让程序 前台或者后台运行而已 
     
    二 screen
    虽然nohup很容易使用,但还是比较“简陋”的,对于简单的命令能够应付过来,对于复杂的需要人机交互的任务就麻烦了。
    其实我们可以使用一个更为强大的实用程序screen。流行的Linux发行版(例如Red Hat Enterprise Linux 4)通常会自带screen实用程序,如果没有的话,可以从GNU screen的官方网站下载。
     1)使用
    执行screen , 按任意键进入子界面;
    我用ping命令开始执行,如果下班了,但是想关闭ssh以后ping继续运行,那么按ctrl+a   再按d   这样暂停了子界面,会显示[detached]的字样,这时候 我回到了父界面;
    用screen –ls查看目前子界面的状态 screen -ls
    There is a screen on: 22292.pts-3.free (Detached)
    1 Socket in /tmp/screens/S-root,这里的22292其实是子界面的pid号;
     
    如果回到子界面 用screen –r 22292,一下子弹到了ping 的子界面;
     
    2)更多帮助 
    可以通过C-a(ctrl+a) ?来查看所有的键绑定,常用的键绑定有:
     
    C-a ?
    显示所有键绑定信息
    C-a w
    显示所有窗口列表
    C-a C-a
    切换到之前显示的窗口
    C-a c
    创建一个新的运行shell的窗口并切换到该窗口
    C-a n
    切换到下一个窗口
    C-a p
    切换到前一个窗口(与C-a n相对)
    C-a 0..9
    切换到窗口0..9
    C-a a
    发送 C-a到当前窗口
    C-a d
    暂时断开screen会话
    C-a k
    杀掉当前窗口
    C-a [
    进入拷贝/回滚模式
     
    其他常用选项:
     
    -c file
    使用配置文件file,而不使用默认的$HOME/.screenrc
    -d|-D [pid.tty.host]
    不开启新的screen会话,而是断开其他正在运行的screen会话
    -h num
    指定历史回滚缓冲区大小为num行
    -list|-ls
    列出现有screen会话,格式为pid.tty.host
    -d -m
    启动一个开始就处于断开模式的会话
    -r sessionowner/ [pid.tty.host]
    重新连接一个断开的会话。多用户模式下连接到其他用户screen会话需要指定sessionowner,需要setuid-root权限
    -S sessionname
    创建screen会话时为会话指定一个名字
    -v
    显示screen版本信息
    -wipe [match]
    同-list,但删掉那些无法连接的会话
     
     
      
    参考:http://chlotte.blog.51cto.com/318402/556540
     
    完! 
     
     
  • 相关阅读:
    Java Output流写入包装问题
    SpringBoot项目单元测试不经过过滤器问题
    SpringSecurity集成启动报 In the composition of all global method configuration, no annotation support was actually activated 异常
    JWT jti和kid属性的说明
    Maven 排除依赖
    第五章 基因概念的发现
    第三章 孟德尔遗传的拓展
    第二章 孟德尔遗传
    第一章 引言
    GWAS全基因组关联分析
  • 原文地址:https://www.cnblogs.com/itech/p/2379523.html
Copyright © 2011-2022 走看看