`

[转]ssh 关闭后仍保持当前运行的进程

阅读更多

转自: http://www.cnitblog.com/201/archive/2010/06/14/66744.html

 

由于各种原因,需要通过ssh登录linux或者unix主机,很多时候我们需要通过ssh的终端启动一 些服务或者运行一些程序,但是默认情况下,当我们关闭ssh终端连接,随之启动的程序也会关闭。原因是:SSH会话关闭时,ssh所关联的pty关闭,系 统会给这个pty所关联的session中的所有进程发送SIGHUP信号,SIGHUP的默认信号处理程序是终止进程,除非进程自己处理了 SIGHUP。

解决方法如下:

使用现成的命令nohup,可以让指定的程序在pty关闭之后继续运行。

运行方法:

#nohup program &

现在就可以正常关闭ssh了,你会发现你的服务依然存在运行

当SecureCRT异常关闭后,后台进程一同关闭的现象罪魁祸首 Signup信号
作者: 2hei 发表于2009年5月19日 22:24 版权声明: 可以转载, 转载时务必以超链形式标明文章原始出处和作者信息及版权声明http://www.2hei.net/mt/2009/05/securecrt-closed-and-sighup.html

症状:使用SecureCRT工具ssh远程连接linux,不退出ssh,而是强行关闭终端(合上笔记本走人)情况下,后台启动的应用也会关闭。
后果:男人哭吧哭吧不是罪!

测试案例:
很明显的是关闭终端后,前台运行的程序会被随之关闭,但是后台进程也会因为终端异常关闭而关掉,如下是一个简单的测试结果:
1、后台执行程序,正常关闭ssh连接,关闭终端的情况:
开启两个终端,其中第一个在后台执行ping操作
ping google.com | tee log.txt &

在第二个终端观察
tail -f log.txt 可以看到日志一直在写
使用pstree命令可以看到ping的进程存在
|-sshd-+-sshd---sshd---bash---pstree
| `-sshd---sshd---bash-+-ping
| `-tee

Ctrl+D 退出第一个终端 然后关闭终端

第二个终端的日志仍然在写,pstree命令:
|-ping
ps x
29427 ? S 0:00 ping google.com
看到ping的进程依然存在

2、后台执行程序,非正常关闭ssh连接(模拟突然掉电或者,未来得及退出ssh,或者ssh仍然连接,直接关闭终端SecureCRT)情况:
同样开启两个终端,其中第一个在后台执行ping操作
ping google.com | tee log.txt &

在第二个终端观察
tail -f log.txt 可以看到日志一直在写
使用pstree命令可以看到ping的进程存在
|-sshd-+-sshd---sshd---bash---pstree
| `-sshd---sshd---bash-+-ping
| `-tee

在不退出ssh的情况下,强行关闭第一个终端(SecureCRT)
在第二个终端观察
tail -f log.txt 可以看到日志已经停止写。
使用pstree命令可以看到ping的进程被停掉
ps aux看不到ping的进程,说明强行关闭终端的情况下后台进程也别kill掉了


查了一下资料,这其中起关键的是 SIGHUP信号
查看所有的信号:
kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL
5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE
9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2
13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD
18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN
22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO
30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1
36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5
40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9
44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13
52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9
56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5
60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1
64) SIGRTMAX

列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。

SIGHUP信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。
登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和后台进程组,一般都属于这个 Session。
当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进程组和后台有终端输出的进程就会中止。
不过有的程序可以捕获这个信号,并忽略它,这样就算退出了Linux登录,后台程序依旧运行。
此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。

以下是网络的相关资料
http://hi.baidu.com/xingfengsoft/blog/item/fedbd05c4d8c7e45faf2c0c8.html
—— secureCRT异常退出和执行exit的区别?
如果直接关闭secureCRT(此处假设是使用ssh登录终端的),那么对于被登录的系统来说,就是远端程序异常断连。和我们突然断网掉线是一样的效果。
这种情况下,用户并没有信号发送,而是sshd服务检测到对端响应超时,然后向之前建立起的连接以及该连接下(ssh登录后会分配一个bash给用户)的进程发送结束信号。如果部分进程忽略sshd发送的信号,进程不退出,在分配给用户的bash退出后,该进程将被init进程接管。

终端异常退出后,后台进程不关闭的解决办法:
1、使用nohup命令: nohup <command> [argument…] & nohup可以屏蔽SIGHUP信号!
2、使用 screen命令。

简单介绍如下:
SCREEN vi /tmp/2hei.net

需要中断连接:
screen Ctrl+a d

查询screen进程:
ps x
20377 ? Ss 0:00 SCREEN vi /tmp/2hei.net

重连 screen -r 20377

参考资料:
http://www.ibm.com/developerworks/cn/linux/l-cn-screen

Linux Jobs等前后台运行命令解

A,Shell支持作用控制,有以下命令:
1. command& 让进程在后台运行
2. jobs 查看后台运行的进程
3. fg %n 让后台运行的进程n到前台来
4. bg %n 让进程n到后台去; 
PS:"n"为jobs查看到的进程编号.

B.下列转:http://blog.chinaunix.net/u/1604/showart_1079559.html

fg、bg、jobs、&、ctrl + z都是跟系统任务有关的,虽然现在基本上不怎么需要用到这些命令,但学会了也是很实用的
一。& 最经常被用到
这个用在一个命令的最后,可以把这个命令放到后台执行
二。ctrl + z
可以将一个正在前台执行的命令放到后台,并且暂停
三。jobs
查看当前有多少在后台运行的命令
四。fg
将后台中的命令调至前台继续运行
如果后台中有多个命令,可以用 fg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)
五。 bg
将一个在后台暂停的命令,变成继续执行
如果后台中有多个命令,可以用bg %jobnumber将选中的命令调出,%jobnumber是通过jobs命令查到的后台正在执行的命令的序号(不是pid)

#Linux下使用Shell命令控制任务 Jobs执行
下列命令可以用来操纵进程任务:
  ps 列出系统中正在运行的进程;
  kill 发送信号给一个或多个进程(经常用来杀死一个进程);
  jobs 列出当前shell环境中已启动的任务状态,若未指定jobsid,则显示所有活动的任务状态信息;如果报告了一个任务的终止(即任务的状态被标记为 Terminated),shell 从当前的shell环境已知的列表中删除任务的进程标识;
  bg 将进程搬到后台运行(Background);
  fg 将进程搬到前台运行(Foreground);

  将job 转移到后台运行
  如果你经常在X图形下工作,你可能有这样的经历:通过终端命令运行一个GUI程序,GUI界面出来了,但是你的终端还停留在原地,你不能在shell中继续执行其他命令了,除非将GUI程序关掉。

  为了使程序执行后终端还能继续接受命令,你可以将进程移到后台运行,使用如下命令运行程序: #假设要运行xmms

  $xmms &

  这样打开xmms后,终端的提示又回来了。现在xmms在后台运行着呢;但万一你运行程序时忘记使用“&”了,又不想重新执行;你可以先使用ctrl+z挂起程序,然后敲入bg命令,这样程序就在后台继续运行了。

  概念:当前任务

  如果后台的任务号有2个,[1],[2];如果当第一个后台任务顺利执行完毕,第二个后台任务还在执行中时,当前任务便会自动变成后台任务号码 “[2]”的后台任务。所以可以得出一点,即当前任务是会变动的。当用户输入“fg”、“bg” 和“stop”等命令时,如果不加任何引号,则所变动的均是当前任务。

  察看jobs
  使用jobs或ps命令可以察看正在执行的jobs。

  jobs命令执行的结果,+表示是一个当前的作业,减号表是是一个当前作业之后的一个作业,jobs -l选项可显示所有任务的PID,jobs的状态可以是running, stopped, Terminated,但是如果任务被终止了(kill),shell 从当前的shell环境已知的列表中删除任务的进程标识;也就是说,jobs命令显示的是当前shell环境中所起的后台正在运行或者被挂起的任务信息;

  进程的挂起

  后台进程的挂起:

  在solaris中通过stop命令执行,通过jobs命令查看job号(假设为num),然后执行stop %num;

  在redhat中,不存在stop命令,可通过执行命令kill -stop PID,将进程挂起;

  当要重新执行当前被挂起的任务时,通过bg %num 即可将挂起的job的状态由stopped改为running,仍在后台执行;当需要改为在前台执行时,执行命令fg %num即可;

  前台进程的挂起:

  ctrl+Z;

  进程的终止

  后台进程的终止:
  方法一:
  通过jobs命令查看job号(假设为num),然后执行kill %num

  方法二:
  通过ps命令查看job的进程号(PID,假设为pid),然后执行kill pid

  前台进程的终止:

  ctrl+c

   kill的其他作用
  kill除了可以终止进程,还能给进程发送其它信号,使用kill -l 可以察看kill支持的信号。

  SIGTERM是不带参数时kill发送的信号,意思是要进程终止运行,但执行与否还得看进程是否支持。如果进程还没有终止,可以使用kill -SIGKILL pid,这是由内核来终止进程,进程不能监听这个信号。
===================
Unix/Linux下一般想让某个程序在后台运行,很多都是使用 & 在程序结尾来让程序自动运行。比如我们要运行mysql在后台:
/usr/local/mysql/bin/mysqld_safe --user=mysql &
 但是我们很多程序并不象mysqld一样可以做成守护进程,可能我们的程序只是普通程序而已,一般这种程序即使使用 & 结尾,如果终端关闭,那么程序也会被关闭。为了能够后台运行,我们需要使用nohup这个命令,比如我们有个start.sh需要在后台运行,并且希望在后台能够一直运行,那么就使用nohup:
nohup /root/start.sh &
在shell中回车后提示:
[~]$ appending output to nohup.out
原程序的的标准输出被自动改向到当前目录下的nohup.out文件,起到了log的作用。
但是有时候在这一步会有问题,当把终端关闭后,进程会自动被关闭,察看nohup.out可以看到在关闭终端瞬间服务自动关闭。
咨询红旗Linux工程师后,他也不得其解,在我的终端上执行后,他启动的进程竟然在关闭终端后依然运行。
在第二遍给我演示时,我才发现我和他操作终端时的一个细节不同:他是在当shell中提示了nohup成功后还需要按终端上键盘任意键退回到shell输入命令窗口,然后通过在shell中输入exit来退出终端;而我是每次在nohup执行成功后直接点关闭程序按钮关闭终端.。所以这时候会断掉该命令所对应的session,导致nohup对应的进程被通知需要一起shutdown。
这个细节有人和我一样没注意到,所以在这儿记录一下了。

附:nohup命令参考
nohup 命令
  用途:不挂断地运行命令。
  语法:nohup Command [ Arg ... ] [ & ]
  描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示"and"的符号)到命令的尾部。
  无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符。
  退出状态:该命令返回下列出口值:
  126 可以查找但不能调用 Command 参数指定的命令。
  127 nohup 命令发生错误或不能查找由 Command 参数指定的命令。
  否则,nohup 命令的退出状态是 Command 参数指定命令的退出状态。
  nohup命令及其输出文件
  nohup命令:如果你正在运行一个进程,而且你觉得在退出帐户时该进程还不会结束,那么可以使用 nohup命令。该命令可以在你退出帐户/关闭终端之后继续运行相应的进程。nohup就是不挂起的意思( n ohang up)。
  该命令的一般形式为:nohup command &
  使用nohup命令提交作业
  如果使用nohup命令提交作业,那么在缺省情况下该作业的所有输出都被重定向到一个名为 nohup.out的文件中,除非另外指定了输出文件:
  nohup command > myout.file 2>&1 &
  在上面的例子中,输出被重定向到myout.file文件中。
  使用 jobs 查看任务。
  使用 fg %n 关闭。
  另外有两个常用的ftp工具ncftpget和ncftpput,可以实现后台的ftp上传和下载,这样就可以利用这些命令在后台上传和下载文件了。
简单而有用的nohup命令在UNIX/LINUX中,普通进程用&符号放到后台运行,如果启动该程序的控制台logout,则该进程随即终止。
  要实现守护进程,一种方法是按守护进程的规则去编程(本站有文章介绍过),比较麻烦;另一种方法是仍然用普通方法编程,然后用nohup命令启动程序:
  nohup<程序名>&
  则控制台logout后,进程仍然继续运行,起到守护进程的作用(虽然它不是严格意义上的守护进程)。
  使用nohup命令后,原程序的的标准输出被自动改向到当前目录下的nohup.out文件,起到了 log的作用,实现了完整的守护进程功能。
  ygwu @ 2005年04月18日 上午10:03
  For example:
  如何远程启动WebLogic服务?
  用telnet远程控制服务器,远程启动WEBLOGIC服务,启动后关闭 telnet,WebLogic服务也跟着停止,这是因为使用telnet启动的进程会随着telnet进程的关闭而关闭。所以我们可以使用一些UNIX 下的命令来做到不关闭。
  使用如下命令:
  nohup startWeblogic.sh&
  如果想要监控标准输出可以使用:
  tail -f nohup.out
  当在后台运行了程序的时候,可以用jobs命令来查看后台作业的状态。在有多个后台程序时,要使用来参数的fg命令将不同序号的后台作业切换到前台上运行。
  当用户启动一个进程的时候,这个进程是运行在前台,使用与相应控制终端相联系的标准输入、输出进行输入和输出。即使将进程的输入输出重定向,并将进程放在后台执行,进程仍然和当前终端设备有关系。正因为如此,在当前的登录会话结束时,控制终端设备将和登录进程相脱离,那么系统就向所有与这个终端相联系的进程发送SIGHUP的信号,通知进程线路已经挂起了,如果程序没有接管这个信号的处理,那么缺省的反应是进程结束。因此普通的程序并不能真正脱离登录会话而运行进程,为了使得在系统登录后还可以正常执行,只有使用命令nohup来启动相应程序。
  使用命令nohup当然可以启动这样的程序,但nohup启动的程序在进程执行完毕就退出,而常见的一些服务进程通常永久的运行在后台,不向屏幕输出结果。在Unix中这些永久的后台进程称为守护进程(daemon)。守护进程通常从系统启动时自动开始执行,系统关闭时才停止。
  在守护进程中,最重要的一个是超级守护进程inetd,这个进程接管了大部分网络服务,但并不是对每个服务都自己进行处理,而是依据连接请求,启动不同的服务程序与客户机打交道。inetd支持网络服务种类在它的设置文件/etc/inet.conf中定义。inet.conf文件中的每一行就对应一个端口地址,当inetd接受到连接这个端口的连接请求时,就启动相应的进程进行处理。使用inetd的好处是系统不必启动很多守护进程,从而节约了系统资源,然而使用inetd启动守护进程相应反应会迟缓一些,不适合用于被密集访问的服务进程。

分享到:
评论

相关推荐

    ssh命令详解和例子

    - `top`:显示系统当前运行的进程状态。 #### VIM编辑器常用快捷键 VIM是一款功能强大的文本编辑器,以下是一些常用的VIM编辑模式快捷键: - `h/j/k/l`:分别表示左/下/上/右移动光标。 - `/`:搜索模式,输入...

    ssh重装步骤.docx

    `lsof` (List Open Files) 工具能显示系统当前打开的文件,包括网络端口,从而确认SSH服务是否正常运行。 此外,对于互联网和CS(计算机科学)领域来说,了解如何安全地管理和配置SSH非常重要,因为SSH广泛应用于...

    Daemon_守护进程

    1. **独立于控制终端**:守护进程不受任何终端的控制,即使用户注销或关闭终端,守护进程也会继续运行。 2. **生命周期长**:守护进程通常在系统启动时启动,并一直运行到系统关闭。 3. **周期性任务或事件处理**:...

    Linux下运行后台任务的方法.docx

    可以使用 ctrl + z 将进程放到后台暂停,然后使用 jobs 查看当前有多少在后台运行的命令,使用 bg 将后台中暂停的作业进程继续运行,使用 fg 将后台中的作业进程调至前台继续运行。 例如: ctrl + z 将 ./test.sh ...

    openstack【juno】入门 【准备篇】一: Ubuntu14.04远程连接(ssh安装)

    如果看到`sshd`进程,表示SSH服务已经在运行。如果没有,可以通过以下命令手动启动SSH服务: ```bash sudo service ssh start ``` SSH的配置文件位于`/etc/ssh/sshd_config`。为了允许root用户通过SSH登录,我们...

    Linux后台进程管理的一些命令小结.pdf

    如果当前正在运行的命令你想暂停并放到后台,可以先按`Ctrl + Z`,这会将进程挂起。然后,你可以通过`bg %jobnumber`命令将挂起的进程唤醒并放到后台继续运行,其中`%jobnumber`是通过`jobs`命令查看到的后台任务的...

    Linux启动过程、运行级别及相关命令

    - **runlevel**:用于查看当前运行级别以及上次运行级别。 - **init [0 1 2 3 4 5 6]**:改变系统运行级别,例如`init 3`切换到多用户无图形界面模式。 **系统服务管理命令**: - **chkconfig**:管理服务的启动、...

    SSH远程登录-screen命令-linux会话命令.docx

    例如,在安装 LNMP 等程序时,网络突然断开,或者其他情况导致不得不与远程 SSH 服务器链接断开,远程执行的命令也被迫停止,只能重新连接,重新运行。这将导致用户的工作被中断,浪费大量时间和精力。 二、Screen ...

    linux技巧之使用screen管理你的远程会话.docx

    使用 nohup 命令可以使进程忽略 SIGHUP 信号,在关闭窗口或断开连接后,进程不会被杀掉。 * 方法二:screen 使用 screen 可以创建一个可以在多个进程间多路复用一个物理终端的窗口管理器。 Screen 的使用方法: 1....

    LINUX教程(各种操作、LINUX所有管理命令、所有磁盘管理、用户管理、服务器管理、进程管理等等。。)

    `ps`显示当前进程状态,`kill`和`pkill`发送信号来结束进程,`nohup`让程序在后台运行不受终端关闭影响,`nice`和`renice`调整进程优先级。 七、系统监视和备份 Linux提供多种工具监控系统性能,如`iostat`分析磁盘...

    Shell脚本实现根据端口号kill相应进程功能

    由于SSH服务默认使用22端口,所以这条命令可以帮助我们找到占用SSH端口的进程。 - `awk '{print $2}'`:从`lsof`的输出中提取第二列数据,即进程ID(PID)。 - `tail -n 2`:取`awk`处理结果的最后两行。由于可能有...

    SecureCRT连接虚拟机中的Linux系统无法连接问题.docx

    在SecureCRT软件中,配置连接参数:Protocol选择SSH2,Port保持默认的22,HostName填写虚拟机的IP地址(如192.168.172.168),UserName填写Ubuntu的用户名。完成这些设置后,尝试连接,如果能够成功,可以输入命令如...

    Win7系统关闭80端口的方法.docx

    2. 然后,在命令提示符中输入"netstat -ano|findstr 80",这将显示当前系统中占用80端口的进程的PID。 3. 通过查看PID,可以确定哪个进程正在占用80端口。 方法二:使用任务管理器 1. 右键点击任务栏空白处,选择...

    Django项目后台不挂断运行的方法

    注意,如果在执行nohup命令后直接关闭SSH窗口,可能会导致该命令对应的session被关闭,进而影响到nohup命令启动的进程。为了避免这种情况,推荐在退出当前账户时使用exit命令,而不是直接关闭SSH窗口。这样可以确保...

    linux运维必备150个命令.docx

    4. uptime:显示当前系统的运行时间 5. file:显示文件类型 6. stat:显示文件的状态信息 7. du:显示当前目录下的文件大小 8. df:显示当前文件系统的磁盘使用情况 9. top:显示当前系统的进程信息 10. free:显示...

    centos7作为web服务器优化.docx

    在确认新用户可以正常登录后,才在iptables中禁用旧的SSH端口。 7. 其他安全措施:可能还包括更新系统,安装必要的安全软件,如SELinux,虽然在描述中已关闭,但通常建议至少保持在permissive模式。监控系统日志,...

    几个好用的Linux命令

    但是需要注意的是,这种方式下,一旦SSH连接被关闭,模型训练也会随之停止。为了防止这种情况发生,可以使用 `nohup` 命令来将进程放到后台运行。 ### 总结 通过以上内容的学习,我们可以了解到,在Linux环境中...

    jar畅游Linux后台

    特点:当前ssh窗口被锁定,可按CTRL + C打断程序运行,或直接关闭窗口,程序退出 jar后台运行方式 方式一 java -jar xxx.jar & //&代表在后台运行 特点:当前ssh窗口不被锁定,但是当窗口关闭时,程序中止运行 方式...

    在UNIX或类UNIX系统(如Linux)中,有许多常用的命令用于文件操作、目录导航、进程管理、系统管理等 以下是一些常用的命令

    `ps` 命令用于查看当前正在运行的进程信息。 2. **top**: 动态显示进程状态。`top` 命令提供了一个实时的动态视图,显示了系统的总体资源使用情况和各个进程的信息。 3. **kill**: 发送信号到进程。`kill` 命令...

Global site tag (gtag.js) - Google Analytics