Linux下系統后臺運行的方法講解

我們經常會碰到這樣的問題,想要在linux 服務器運行一些耗時較長的任務, 結果卻由于網絡的不穩定導致任務中途失敗。如何讓命令提交后不受本地關閉終端窗口/網絡斷開連接的干擾呢?

下面列舉了三種方法,可以很方便的滿足上述需求。

問題分析:

我們知道,當用戶注銷(logout)或者網絡斷開時,終端會收到 HUP(hangup)信號從而關閉其所有子進程。因此,我們的解決辦法就有兩種途徑:要么讓進程忽略 HUP 信號,要么讓進程運行在新的會話里從而成為不屬于此終端的子進程。

三種解決辦法:

1. nohup

nohup 無疑是我們首先想到的辦法。顧名思義,nohup 的用途就是讓提交的命令忽略 hangup 信號。

nohup 的使用是十分方便的,只需在要處理的命令前加上 nohup 即可,標準輸出和標準錯誤缺省會被重定向到 nohup.out 文件中。一般我們可在結尾加上”&”來將命令同時放入后臺運行,也可用”>filename 2>&1″來更改缺省的重定向文件名。

nohup 示例

[root@pythontab?~]#?nohup?ping?www.php.cn?&  [1]?3059  nohup:?appending?output?to?`nohup.out'  [root@pythontab?~]#?ps?-ef?|grep?3059  root??????3059???984??0?15:06?pts/3????00:00:00?ping?www.php.cn  root??????3067???984??0?15:06?pts/3????00:00:00?grep?3059  [root@pythontab?~]#

2。setsid

nohup 無疑能通過忽略 HUP 信號來使我們的進程避免中途被中斷,但如果我們換個角度思考,如果我們的進程不屬于接受 HUP 信號的終端的子進程,那么自然也就不會受到 HUP 信號的影響了。setsid 就能幫助我們做到這一點。

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

setsid 示例

[root@pythontab?~]#?setsid?ping?www.php.cn  [root@pythontab?~]#?ps?-ef?|grep?www.php.cn  root?????31094?????1??0?07:28??????????00:00:00?ping?www.php.cn  root?????31102?29217??0?07:29?pts/4????00:00:00?grep?www.php.cn  [root@pythontab?~]#

值得注意的是,上例中我們的進程 ID(PID)為31094,而它的父 ID(PPID)為1(即為 init 進程 ID),并不是當前終端的進程 ID。

3。& subshell

這里還有一個關于 subshell 的小技巧。我們知道,將一個或多個命名包含在“()”中就能讓這些命令在子 shell 中運行中,從而擴展出很多有趣的功能,我們現在要討論的就是其中之一。

當我們將”&”也放入“()”內之后,我們就會發現所提交的作業并不在作業列表中,也就是說,是無法通過jobs來查看的。讓我們來看看為什么這樣就能躲過 HUP 信號的影響吧。

subshell 示例

[root@pythontab?~]#?(ping?www.php.cn?&)  [root@pythontab?~]#?ps?-ef?|grep?www.php.cn  root?????16270?????1??0?16:13?pts/4????00:00:00?ping?www.php.cn  root?????16278?15362??0?16:13?pts/4????00:00:00?grep?www.php.cn  [root@pythontab?~]#

從上例中可以看出,新提交的進程的父 ID(PPID)為1(init 進程的 PID),并不是當前終端的進程 ID。因此并不屬于當前終端的子進程,從而也就不會受到當前終端的 HUP 信號的影響了。

比較而言,我更喜歡用setsid,簡單實用。當然,這里看大家喜好即可,效果上差別不大。

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享