nohup 讓進程在後臺可靠運行的幾種方法
1. nohup
nohup 無疑是我們首先想到的辦法。顧名思義,nohup 的用途就是讓提交的命令忽略 hangup 信號。
nohup 的使用是十分方便的,只需在要處理的命令前加上 nohup 即可,標準輸出和標準錯誤缺省會被重定向到 nohup.out 文件中。一般我們可在結尾加上"&"來將命令同時放入後臺運行,也可用">filename 2>&1"
來更改缺省的重定向文件名。
nohup 示例
[root@~]# nohup ping www.ibm.com &
[1] 3059
nohup: appending output to `nohup.out‘
[root@~]# 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@~]#
該命令的一般形式為:nohup command &
如果使用nohup命令提交作業,那麽在缺省情況下該作業的所有輸出都被重定向到一個名為nohup.out的文件中,除非另外指定了輸出文件:
nohup command > myout.file 2>&1 &
在上面的例子中,輸出被重定向到myout.file文件中。
使用 jobs 查看任務。
使用 fg %n 關閉。
當你成功地提交進程以後,就會顯示出一個進程號,可以用它來監控該進程,或殺死它。(ps -ef | grep 進程號 或者 kill -9 進程號)使用了nohup之後,很多人就這樣不管了,其實這樣有可能在當前賬戶非正常退出或者結束的時候,命令還是自己結束了。所以在使用nohup命令後臺運行命令之後,需要使用exit正常退出當前賬戶,這樣才能保證命令一直在後臺運行。
ctrl + z
可以將一個正在前臺執行的命令放到後臺,並且處於暫停狀態。
Ctrl+c
終止前臺命令。
jobs
查看當前有多少在後臺運行的命令。
2>&1解析
command >out.file 2>&1 &
command>out.file是將command的輸出重定向到out.file文件,即輸出內容不打印到屏幕上,而是輸出到out.file文件中。
2>&1 是將標準出錯重定向到標準輸出,這裏的標準輸出已經重定向到了out.file文件,即將標準出錯也輸出到out.file文件中。最後一個&, 是讓該命令在後臺執行。
試想2>1代表什麽,2與>結合代表錯誤重定向,而1則代表錯誤重定向到一個文件1,而不代表標準輸出;換成2>&1,&與1結合就代表標準輸出了,就變成錯誤重定向到標準輸出.
退出任務
如果運行的任務在當前 shell 終端,可以通過 jobs 命令查詢相關信息,並且殺掉進程。
# 查看當前 shell 終端的後臺運行任務進程信息
$ jobs
[1]+ Running nohup java -jar adapter-minisite.jar /tomcat-1 /tomcat-2 > logs.txt 2>&1 &
# 殺掉任務號
$ kill %1
# 找到 pid
$ jobs -l
[1]+ 11076
$ kill 11076
#
$ fg %n # 置為前端運行
Ctrl + c # 退出
如果非當前 shell 終端,可以通過 ps auxf | grep ‘xxxxx‘ 獲取 pid 然後 kill pid。
2. setsid
nohup 無疑能通過忽略 HUP 信號來使我們的進程避免中途被中斷,但如果我們換個角度思考,如果我們的進程不屬於接受 HUP 信號的終端的子進程,那麽自然也就不會受到 HUP 信號的影響了。 setsid 的使用也是非常方便的,也只需在要處理的命令前加上 setsid 即可。setsid 示例
[root@~]# setsid ping www.ibm.com
[root@~]# 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@~]# (ping www.ibm.com &)
[root@~]# 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
4. 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
來將它放入後臺並繼續運行。需要註意的是,如果掛起會影響當前進程的運行結果,請慎用此方法。
5. screen
場景:
我們已經知道了如何讓進程免受 HUP 信號的影響,但是如果有大量這種命令需要在穩定的後臺裏運行,如何避免對每條命令都做這樣的操作呢?
解決方法:
此時最方便的方法就是 screen 了。簡單的說,screen 提供了 ANSI/VT100 的終端模擬器,使它能夠在一個真實終端下運行多個全屏的偽終端。screen 的參數很多,具有很強大的功能,我們在此僅介紹其常用功能以及簡要分析一下為什麽使用 screen 能夠避免 HUP 信號的影響。
使用 screen 很方便,有以下幾個常用選項:
- 用
screen -dmS session name
來建立一個處於斷開模式下的會話(並指定其會話名)。 - 用
screen -list
來列出所有會話。 - 用
screen -r session name
來重新連接指定會話。 - 用快捷鍵
CTRL-a d
來暫時斷開當前會話。
REF:
https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/
nohup 讓進程在後臺可靠運行的幾種方法