nohup/setsid/&
場景:如果只是臨時有乙個命令需要長時間執行,什麼方法能最簡便的保證它在後台穩定執行呢?
解決方法:
我們知道,當使用者登出(logout)或者網路斷開時,終端會收到 hup(hangup)訊號從而關閉其所有子程序。
因此,我們的解決辦法就有兩種途徑:要麼讓程序忽略 hup 訊號,要麼讓程序執行在新的會話裡從而成為不屬於此終端的子程序。
1. nohup
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.
nohup 無疑是我們首先想到的辦法。顧名思義,nohup 的用途就是讓提交的命令忽略 hangup 訊號。
只需在要處理的命令前加上 nohup 即可,標準輸出和標準錯誤缺省會被重定向到 nohup.out 檔案中。一般我們可在結尾加上"&"來將
命令同時放入後台執行,也可用">filename 2>&1"來更改預設的重定向檔名。
2。setsid
nohup 無疑能通過忽略 hup 訊號來使我們的程序避免中途被中斷,但如果我們換個角度思考,如果我們的程序不屬於接受 hup 訊號的
終端的子程序,那麼自然也就不會受到 hup 訊號的影響了。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 的使用也是非常方便的,也只需在要處理的命令前加上 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
3。&這裡還有乙個關於 subshell 的小技巧。我們知道,將乙個或多個命名包含在「()」中就能讓這些命令在子 shell 中執行中,從而擴充套件出很多
有趣的功能,我們現在要討論的就是其中之一。
當我們將"&"也放入「()」內之後,我們就會發現所提交的作業並不在作業列表中,也就是說,是無法通過jobs來檢視的。讓我們來看看
為什麼這樣就能躲過 hup 訊號的影響吧。
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 ~]#
從上例中可以看出,新提交的程序的父 id(ppid)為1(init 程序的 pid),並不是當前終端的程序 id。因此並不屬於當前終端的子程序,
從而也就不會受到當前終端的 hup 訊號的影響了。
disown
場景:我們已經知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 hup 訊號的影響。但是如果我們未加任何處理就已經提交了命令,
該如何補救才能讓它避免 hup 訊號的影響呢?
解決方法:
這時想加 nohup 或者 setsid 已經為時已晚,只能通過作業排程和 disown 來解決這個問題了。
用disown -h jobspec來使某個作業忽略hup訊號。
用disown -ah 來使所有的作業都忽略hup訊號。
用disown -rh 來使正在執行的作業忽略hup訊號。
需要注意的是,當使用過 disown 之後,會將把目標作業從作業列表中移除,我們將不能再使用jobs來檢視它,但是依然能夠用ps -ef查詢到它。
但是還有乙個問題,這種方法的操作物件是作業,如果我們在執行命令時在結尾加了"&"來使它成為乙個作業並在後台執行,那麼就萬事大吉了,
我們可以通過jobs命令來得到所有作業的列表。但是如果並沒有把當前命令作為作業來執行,如何才能得到它的作業號呢?答案就是用 ctrl-z
(按住ctrl鍵的同時按住z鍵)了!
ctrl-z 的用途就是將當前程序掛起(suspend),然後我們就可以用jobs命令來查詢它的作業號,再用bg jobspec來將它放入後台並繼續執行。
需要注意的是,如果掛起會影響當前程序的執行結果,請慎用此方法。
disown 示例1(如果提交命令時已經用「&」將命令放入後台執行,則可以直接使用「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(如果提交命令時未使用「&」將命令放入後台執行,可使用 ctrl-z 和「bg」將其放入後台,再使用「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]#
總結現在幾種方法已經介紹完畢,我們可以根據不同的場景來選擇不同的方案。nohup/setsid 無疑是臨時需要時最方便的方法,
disown 能幫助我們來事後補救當前已經在執行了的作業
Linux中長時間執行程式的方法
一 場景 如果臨時有乙個命令需要長時間執行,比如 python hello.py 什麼方法能最簡便的保證它在後台穩定執行呢?解決方法 當使用者登出 logout 或者網路斷開時,終端會收到 hup hangup 訊號從而關閉其所有子程序。因此,我們的解決辦法就有兩種途徑 要麼讓程序忽略 hup 訊號...
防止shell指令碼長時間執行導致ssh超時
在一些對安全性要求較高的場景下。ssh的超時時間是管理員預先設定好的,在閒置一段時間後ssh連線會自己主動斷開。這樣的情況下假設通過ssh執行指令碼,而指令碼執行時間又比較長的話。會導致sshclient和server長時間無互動而超時,命令執行失敗。使用bash子程序能夠解決這樣的問題,思路是由子...
Linux執行指令碼
首先指令碼需要有執行許可權 chmod u x file.sh 執行指令碼有三種方法 1.file.sh 特點 開啟bash子程序來執行,也就是開啟額外的程序來進行,不影響原程序的變數 配置等 2.bash file.sh 特點 和.file.sh相同 3.source file.sh 或者 fil...