惌q程在断开q接后依然保持运行?如果该进E已l开始运行了该如何补救? 如果有大量这c需求如何简化操作?
我们l常会碰到这L问题Q用 telnet/ssh d了远E的 Linux 服务器,q行了一些耗时较长的Q务, l果却由于网l的不稳定导致Q务中途失败。如何让命o提交后不受本地关闭终端窗?|络断开q接的干扰呢Q下面D了一些例子, 您可以针对不同的场景选择不同的方式来处理q个问题?/p>
nohup/setsid/&
场景Q?/p>
如果只是临时有一个命令需要长旉q行Q什么方法能最便的保证它在后台E_q行呢?
解决ҎQ?/p>
我们知道Q当用户注销QlogoutQ或者网l断开Ӟl端会收?HUPQhangupQ信号从而关闭其所有子q程。因此,我们的解军_法就有两U途径Q要么让q程忽略 HUP 信号Q要么让q程q行在新的会话里从而成Z属于此终端的子进E?/p>
1. nohup
nohup 无疑是我们首先想到的办法。顾名思义Qnohup 的用途就是让提交的命令忽?hangupQ在 Unix 的早期版本中Q每个终端都会通过 modem 和系l通讯。当用户 logout Ӟmodem ׃挂断Qhang upQ电话?同理Q当 modem 断开q接Ӟ׃l终端发?hangup 信号来通知其关闭所有子q程。) 信号。让我们先来看一?nohup 的帮助信?br /> NOHUP(1) User Commands NOHUP(1)
NAME
nohup - run a command immune to hangups, with output to a non-tty
SYNOPSIS
nohup COMMAND [ARG]...
nohup OPTION
DESCRIPTION
Run COMMAND, ignoring hangup signals.
--help display this help and exit
--version
output version information and exit
可见Qnohup 的用是十分方便的,只需在要处理的命令前加上 nohup 卛_Q标准输出和标准错误~省会被重定向到 nohup.out 文g中。一般我们可在结֊?&"来将命o同时攑օ后台q行Q也可用">filename 2>&1"来更改缺省的重定向文件名?/p>
nohup CZ
[root@pvcent107 ~]# nohup ping www.ibm.com &
[1] 3059
nohup: appending output to `nohup.out'
[root@pvcent107 ~]# ps -ef |grep 3059
root 3059 984 0 21:06 pts/3 00:00:00 ping www.ibm.com
root 3067 984 0 21:06 pts/3 00:00:00 grep 3059
[root@pvcent107 ~]#
2。setsid
nohup 无疑能通过忽略 HUP 信号来我们的进E避免中途被中断Q但如果我们换个角度思考,如果我们的进E不属于接受 HUP 信号的终端的子进E,那么自然也就不会受到 HUP 信号的媄响了。setsid p帮助我们做到q一炏V让我们先来看一?setsid 的帮助信息:
SETSID(8) Linux Programmer’s Manual SETSID(8) NAME setsid - run a program in a new session SYNOPSIS setsid program [ arg ... ] DESCRIPTION setsid runs a program in a new session.
可见 setsid 的用也是非常方便的Q也只需在要处理的命令前加上 setsid 卛_?/p>
setsid CZ
[root@pvcent107 ~]# setsid ping www.ibm.com
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root 31094 1 0 07:28 ? 00:00:00 ping www.ibm.com
root 31102 29217 0 07:29 pts/4 00:00:00 grep www.ibm.com
[root@pvcent107 ~]#
值得注意的是Q上例中我们的进E?ID(PID)?1094Q而它的父 IDQPPIDQؓ1Q即?init q程 IDQ,q不是当前终端的q程 ID。请此例与nohup 例中的父 ID 做比较?/p>
3?amp;
q里q有一个关?subshell 的小技巧。我们知道,一个或多个命名包含?#8220;()”中就能让q些命o在子 shell 中运行中Q从而扩展出很多有趣的功能,我们现在要讨论的是其中之一?/p>
当我们将"&"也放?#8220;()”内之后,我们׃发现所提交的作业ƈ不在作业列表中,也就是说Q是无法通过jobs来查看的。让我们来看看ؓ什么这样就能躲q?HUP 信号的媄响吧?/p>
subshell CZ
[root@pvcent107 ~]# (ping www.ibm.com &)
[root@pvcent107 ~]# ps -ef |grep www.ibm.com
root 16270 1 0 14:13 pts/4 00:00:00 ping www.ibm.com
root 16278 15362 0 14:13 pts/4 00:00:00 grep www.ibm.com
[root@pvcent107 ~]#
从上例中可以看出Q新提交的进E的?IDQPPIDQؓ1Qinit q程?PIDQ,q不是当前终端的q程 ID。因此ƈ不属于当前终端的子进E,从而也׃会受到当前终端的 HUP 信号的媄响了
screen
场景Q?/p>
我们已经知道了如何让q程免受 HUP 信号的媄响,但是如果有大量这U命令需要在E_的后台里q行Q如何避免对每条命o都做q样的操作呢Q?/p>
解决ҎQ?/p>
此时最方便的方法就?screen 了。简单的_screen 提供?ANSI/VT100 的终端模拟器Q它能够在一个真实终端下q行多个全屏的伪l端。screen 的参数很多,h很强大的功能Q我们在此仅介绍其常用功能以及简要分析一下ؓ什么?screen 能够避免 HUP 信号的媄响。我们先看一?screen 的帮助信息:
SCREEN(1) SCREEN(1)
NAME
screen - screen manager with VT100/ANSI terminal emulation
SYNOPSIS
screen [ -options ] [ cmd [ args ] ]
screen -r [[pid.]tty[.host]]
screen -r sessionowner/[[pid.]tty[.host]]
DESCRIPTION
Screen is a full-screen window manager that multiplexes a physical
terminal between several processes (typically interactive shells).
Each virtual terminal provides the functions of a DEC VT100 terminal
and, in addition, several control functions from the ISO 6429 (ECMA
48, ANSI X3.64) and ISO 2022 standards (e.g. insert/delete line and
support for multiple character sets). There is a scrollback history
buffer for each virtual terminal and a copy-and-paste mechanism that
allows moving text regions between windows.
使用 screen 很方便,有以下几个常用选项Q?/p>
用screen -dmS session name 来徏立一个处于断开模式下的会话Qƈ指定其会话名Q?br /> 用screen -list 来列出所有会话?br /> 用screen -r session name 来重新连接指定会话?br /> 用快捷键CTRL-a d 来暂时断开当前会话?/p>
screen CZ
[root@pvcent107 ~]# screen -dmS Urumchi
[root@pvcent107 ~]# screen -list
There is a screen on:
12842.Urumchi (Detached)
1 Socket in /tmp/screens/S-root.
[root@pvcent107 ~]# screen -r Urumchi
当我们用“-r”q接?screen 会话后,我们可以在q个伪终端里面ؓ所ƲؓQ再也不用担?HUP 信号会对我们的进E造成影响Q也不用l每个命令前都加?#8220;nohup”或?#8220;setsid”了。这是ؓ什么呢Q让我来看一下下面两个例子吧?/p>
1. 未?screen 时新q程的进E树
[root@pvcent107 ~]# ping www.google.com &
[1] 9499
[root@pvcent107 ~]# pstree -H 9499
init─┬─Xvnc
├─acpid
├─atd
├─2*[sendmail]
├─sshd─┬─sshd───bash───pstree
?nbsp; └─sshd───bash───ping
我们可以看出Q未使用 screen 时我们所处的 bash ?sshd 的子q程Q当 ssh 断开q接ӞHUP 信号自然会媄响到它下面的所有子q程Q包括我们新建立?ping q程Q?/p>
2. 使用?screen 后新q程的进E树
[root@pvcent107 ~]# screen -r Urumchi
[root@pvcent107 ~]# ping www.ibm.com &
[1] 9488
[root@pvcent107 ~]# pstree -H 9488
init─┬─Xvnc
├─acpid
├─atd
├─screen───bash───ping
├─2*[sendmail]
而用了 screen 后就不同了,此时 bash ?screen 的子q程Q?screen ?initQPID?Q的子进E。那么当 ssh 断开q接ӞHUP 信号自然不会影响?screen 下面的子q程了?/p>
ȝ
现在几种Ҏ已经介绍完毕Q我们可以根据不同的场景来选择不同的方案。nohup/setsid 无疑是旉要时最方便的方法,disown 能帮助我们来事后补救当前已经在运行了的作业,?screen 则是在大扚w操作时不二的选择?br />