Linux 下讓進(jìn)程在后臺(tái)可靠運(yùn)行的幾種方法

作者:岳國(guó)帥
原文地址:http://www.linuxprobe.com/process-run-background/

想讓進(jìn)程在斷開(kāi)連接后依然保持運(yùn)行左痢?如果該進(jìn)程已經(jīng)開(kāi)始運(yùn)行了該如何補(bǔ)救屎暇? 如果有大量這類需求如何簡(jiǎn)化操作规个?

我們經(jīng)常會(huì)碰到這樣的問(wèn)題,用 telnet/ssh 登錄了遠(yuǎn)程的 Linux 服務(wù)器捌议,運(yùn)行了一些耗時(shí)較長(zhǎng)的任務(wù), 結(jié)果卻由于網(wǎng)絡(luò)的不穩(wěn)定導(dǎo)致任務(wù)中途失敗映皆。如何讓命令提交后不受本地關(guān)閉終端窗口租幕、網(wǎng)絡(luò)斷開(kāi)連接的干擾呢?

下面舉了一些例子着倾, 您可以針對(duì)不同的場(chǎng)景選擇不同的方式來(lái)處理這個(gè)問(wèn)題拾酝。

nohup/setsid/&

場(chǎng)景:

如果只是臨時(shí)有一個(gè)命令需要長(zhǎng)時(shí)間運(yùn)行,什么方法能最簡(jiǎn)便的保證它在后臺(tái)穩(wěn)定運(yùn)行呢卡者?

我們知道蒿囤,當(dāng)用戶注銷logout或者網(wǎng)絡(luò)斷開(kāi)時(shí),終端會(huì)收到 HUP(hangup)信號(hào)從而關(guān)閉其所有子進(jìn)程崇决。因此材诽,我們的解決辦法就有兩種途徑:要么讓進(jìn)程忽略 HUP 信號(hào),要么讓進(jìn)程運(yùn)行在新的會(huì)話里從而成為不屬于此終端的子進(jìn)程恒傻。

1.nohup

nohup 無(wú)疑是我們首先想到的辦法脸侥。顧名思義,nohup 的用途就是讓提交的命令忽略 hangup 信號(hào)盈厘。

nohup 的使用是十分方便的睁枕,只需在要處理的命令前加上 nohup 即可,標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤缺省會(huì)被重定向到 nohup.out 文件中。一般我們可在結(jié)尾加上"&"來(lái)將命令同時(shí)放入后臺(tái)運(yùn)行外遇,也可用">filename 2>&1"來(lái)更改缺省的重定向文件名注簿。

nohup 示例:

[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 無(wú)疑能通過(guò)忽略 HUP 信號(hào),來(lái)使我們的進(jìn)程避免中途被中斷跳仿。但如果我們換個(gè)角度思考诡渴,如果我們的進(jìn)程不屬于接受 HUP 信號(hào)的終端的子進(jìn)程,那么自然也就不會(huì)受到 HUP 信號(hào)的影響了菲语。setsid 就能幫助我們做到這一點(diǎn)妄辩。

setsid 的使用也是非常方便的,也只需在要處理的命令前加上 setsid 即可山上。

setsid 示例:

[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 ~]#

值得注意的是恩袱,上例中我們的進(jìn)程 ID(PID)為31094,而它的父 ID(PPID)為1(即為 init 進(jìn)程 ID)胶哲,并不是當(dāng)前終端的進(jìn)程 ID畔塔。請(qǐng)將此例與nohup 例中的父 ID 做比較。

3.&

這里還有一個(gè)關(guān)于 subshell 的小技巧鸯屿。我們知道澈吨,將一個(gè)或多個(gè)命名包含在“()”中就能讓這些命令在子 shell 中運(yùn)行中,從而擴(kuò)展出很多有趣的功能寄摆,我們現(xiàn)在要討論的就是其中之一谅辣。

當(dāng)我們將"&"也放入“()”內(nèi)之后,我們就會(huì)發(fā)現(xiàn)所提交的作業(yè)并不在作業(yè)列表中婶恼,也就是說(shuō)桑阶,是無(wú)法通過(guò)jobs來(lái)查看的。讓我們來(lái)看看勾邦,為什么這樣就能躲過(guò) HUP 信號(hào)的影響吧蚣录。

subshell 示例:

[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 ~]#

從上例中可以看出,新提交的進(jìn)程的父 ID(PPID)為1(init 進(jìn)程的 PID)眷篇,并不是當(dāng)前終端的進(jìn)程 ID萎河。因此并不屬于當(dāng)前終端的子進(jìn)程,從而也就不會(huì)受到當(dāng)前終端的 HUP 信號(hào)的影響了蕉饼。

disown

我們已經(jīng)知道虐杯,如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信號(hào)的影響。但是如果我們未加任何處理就已經(jīng)提交了命令昧港,該如何補(bǔ)救才能讓它避免 HUP 信號(hào)的影響呢擎椰?

這時(shí)想加 nohup 或者 setsid 已經(jīng)為時(shí)已晚,只能通過(guò)作業(yè)調(diào)度和 disown 來(lái)解決這個(gè)問(wèn)題了创肥。

讓我們來(lái)看一下 disown 的幫助信息:

disown [-ar] [-h] [jobspec ...]
    Without options, each jobspec is  removed  from  the  table  of
    active  jobs.   If  the -h option is given, each jobspec is not
    removed from the table, but is marked so  that  SIGHUP  is  not
    sent  to the job if the shell receives a SIGHUP.  If no jobspec
    is present, and neither the -a nor the -r option  is  supplied,
    the  current  job  is  used.  If no jobspec is supplied, the -a
    option means to remove or mark all jobs; the -r option  without
    a  jobspec  argument  restricts operation to running jobs.  The
    return value is 0 unless a jobspec does  not  specify  a  valid
    job.

我們可以用如下方式來(lái)達(dá)成我們的目的达舒。

  • 靈活運(yùn)用 CTRL-z

在我們的日常工作中值朋,我們可以用CTRL-z來(lái)將當(dāng)前進(jìn)程掛起到后臺(tái)暫停運(yùn)行,執(zhí)行一些別的操作休弃,然后再用fg來(lái)將掛起的進(jìn)程重新放回前臺(tái)(也可用bg來(lái)將掛起的進(jìn)程放在后臺(tái))繼續(xù)運(yùn)行。這樣我們就可以在一個(gè)終端內(nèi)靈活切換運(yùn)行多個(gè)任務(wù)圈膏,這一點(diǎn)在調(diào)試代碼時(shí)尤為有用塔猾。因?yàn)閷⒋a編輯器掛起到后臺(tái)再重新放回時(shí),光標(biāo)定位仍然停留在上次掛起時(shí)的位置稽坤,避免了重新定位的麻煩丈甸。

用disown -h jobspec來(lái)使某個(gè)作業(yè)忽略HUP信號(hào)。
用disown -ah 來(lái)使所有的作業(yè)都忽略HUP信號(hào)尿褪。
用disown -rh 來(lái)使正在運(yùn)行的作業(yè)忽略HUP信號(hào)睦擂。

需要注意的是,當(dāng)使用過(guò) disown 之后杖玲,會(huì)將把目標(biāo)作業(yè)從作業(yè)列表中移除顿仇,我們將不能再使用jobs來(lái)查看它,但是依然能夠用ps -ef查找到它摆马。

但是還有一個(gè)問(wèn)題臼闻,這種方法的操作對(duì)象是作業(yè),如果我們?cè)谶\(yùn)行命令時(shí)在結(jié)尾加了"&"來(lái)使它成為一個(gè)作業(yè)并在后臺(tái)運(yùn)行囤采,那么就萬(wàn)事大吉了述呐,我們可以通過(guò)jobs命令來(lái)得到所有作業(yè)的列表。

但是如果并沒(méi)有把當(dāng)前命令作為作業(yè)來(lái)運(yùn)行乓搬,如何才能得到它的作業(yè)號(hào)呢棉磨?答案就是用CTRL-z(按住Ctrl鍵的同時(shí)按住z鍵)了频敛!

CTRL-z的用途就是將當(dāng)前進(jìn)程掛起Suspend差油,然后我們就可以用jobs命令來(lái)查詢它的作業(yè)號(hào)发侵,再用bg jobspec來(lái)將它放入后臺(tái)并繼續(xù)運(yùn)行盅弛。

需要注意的是,如果掛起會(huì)影響當(dāng)前進(jìn)程的運(yùn)行結(jié)果,請(qǐng)慎用此方法。

disown 示例1:(如果提交命令時(shí)已經(jīng)用“&”將命令放入后臺(tái)運(yùn)行,則可以直接使用“disown”)

[root@pvcent107 build]# cp -r testLargeFile largeFile &
[1] 4825
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile
root      4825   968  1 09:46 pts/4    00:00:00 cp -i -r testLargeFile largeFile
root      4853   968  0 09:46 pts/4    00:00:00 grep largeFile
[root@pvcent107 build]# logout

disown 示例2:(如果提交命令時(shí)未使用“&”將命令放入后臺(tái)運(yùn)行气忠,可使用CTRL-z和“bg”將其放入后臺(tái),再使用“disown”)

[root@pvcent107 build]# cp -r testLargeFile largeFile2

[1]+  Stopped                 cp -i -r testLargeFile largeFile2
[root@pvcent107 build]# bg %1
[1]+ cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# jobs
[1]+  Running                 cp -i -r testLargeFile largeFile2 &
[root@pvcent107 build]# disown -h %1
[root@pvcent107 build]# ps -ef |grep largeFile2
root      5790  5577  1 10:04 pts/3    00:00:00 cp -i -r testLargeFile largeFile2
root      5824  5577  0 10:05 pts/3    00:00:00 grep largeFile2
[root@pvcent107 build]#

screen

我們已經(jīng)知道了如何讓進(jìn)程免受 HUP 信號(hào)的影響,但是如果有大量這種命令需要在穩(wěn)定的后臺(tái)里運(yùn)行,如何避免對(duì)每條命令都做這樣的操作呢?

此時(shí)最方便的方法就是 screen 了身辨。簡(jiǎn)單的說(shuō)号俐,screen 提供了 ANSI/VT100 的終端模擬器洗贰,使它能夠在一個(gè)真實(shí)終端下運(yùn)行多個(gè)全屏的偽終端绎晃。screen 的參數(shù)很多杂曲,具有很強(qiáng)大的功能庶艾,我們?cè)诖藘H介紹其常用功能以及簡(jiǎn)要分析一下,為什么使用 screen 能夠避免 HUP 信號(hào)的影響擎勘。我們先看一下 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 很方便咱揍,有以下幾個(gè)常用選項(xiàng):

用screen -dmS session name來(lái)建立一個(gè)處于斷開(kāi)模式下的會(huì)話(并指定其會(huì)話名)。
用screen -list 來(lái)列出所有會(huì)話棚饵。
用screen -r session name來(lái)重新連接指定會(huì)話煤裙。
用快捷鍵CTRL-a d 來(lái)暫時(shí)斷開(kāi)當(dāng)前會(huì)話。

screen 示例:

[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

當(dāng)我們用“-r”連接到 screen 會(huì)話后噪漾,我們就可以在這個(gè)偽終端里面為所欲為硼砰,再也不用擔(dān)心 HUP 信號(hào)會(huì)對(duì)我們的進(jìn)程造成影響,也不用給每個(gè)命令前都加上“nohup”或者“setsid”了欣硼。這是為什么呢题翰?讓我來(lái)看一下,下面兩個(gè)例子吧诈胜。

1.未使用 screen 時(shí)新進(jìn)程的進(jìn)程樹(shù):

[root@pvcent107 ~]# ping www.google.com &
[1] 9499
[root@pvcent107 ~]# pstree -H 9499
init─┬─Xvnc
     ├─acpid
     ├─atd
     ├─2*[sendmail] 
     ├─sshd─┬─sshd───bash───pstree
     │       └─sshd───bash───ping

我們可以看出豹障,未使用 screen 時(shí)我們所處的bashsshd的子進(jìn)程,當(dāng)ssh斷開(kāi)連接時(shí)焦匈,HUP信號(hào)自然會(huì)影響到它下面的所有子進(jìn)程(包括我們新建立的 ping 進(jìn)程)沼填。

2.使用了 screen 后新進(jìn)程的進(jìn)程樹(shù):

[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 后就不同了,此時(shí)bashscreen的子進(jìn)程括授,而 screeninit(PID為1)的子進(jìn)程坞笙。那么當(dāng)ssh斷開(kāi)連接時(shí)岩饼,HUP信號(hào)自然不會(huì)影響到screen下面的子進(jìn)程了。

總結(jié)

現(xiàn)在幾種方法已經(jīng)介紹完畢薛夜,我們可以根據(jù)不同的場(chǎng)景來(lái)選擇不同的方案籍茧。nohup/setsid無(wú)疑是臨時(shí)需要時(shí)最方便的方法,disown能幫助我們來(lái)事后補(bǔ)救當(dāng)前已經(jīng)在運(yùn)行了的作業(yè)梯澜,而screen則是在大批量操作時(shí)不二的選擇了寞冯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市晚伙,隨后出現(xiàn)的幾起案子吮龄,更是在濱河造成了極大的恐慌,老刑警劉巖咆疗,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漓帚,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡午磁,警方通過(guò)查閱死者的電腦和手機(jī)尝抖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)迅皇,“玉大人昧辽,你說(shuō)我怎么就攤上這事〉峭牵” “怎么了搅荞?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)框咙。 經(jīng)常有香客問(wèn)我咕痛,道長(zhǎng),這世上最難降的妖魔是什么扁耐? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任暇检,我火速辦了婚禮,結(jié)果婚禮上婉称,老公的妹妹穿的比我還像新娘块仆。我一直安慰自己,他們只是感情好王暗,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布悔据。 她就那樣靜靜地躺著,像睡著了一般俗壹。 火紅的嫁衣襯著肌膚如雪科汗。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天绷雏,我揣著相機(jī)與錄音头滔,去河邊找鬼怖亭。 笑死,一個(gè)胖子當(dāng)著我的面吹牛坤检,可吹牛的內(nèi)容都是我干的兴猩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼早歇,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼倾芝!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起箭跳,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤晨另,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后谱姓,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體借尿,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年逝段,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了垛玻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片割捅。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奶躯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出亿驾,到底是詐尸還是另有隱情嘹黔,我是刑警寧澤,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布莫瞬,位于F島的核電站儡蔓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏疼邀。R本人自食惡果不足惜喂江,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望旁振。 院中可真熱鬧获询,春花似錦、人聲如沸拐袜。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蹬铺。三九已至尝哆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間甜攀,已是汗流浹背秋泄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工琐馆, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恒序。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓啡捶,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親奸焙。 傳聞我的和親對(duì)象是個(gè)殘疾皇子瞎暑,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容