Linux 將進程放入后台執行,解決網絡,ssh斷開導致進程結束(nohup, setsid, &, disown)


Linux 將進程放入后台執行,解決網絡,ssh斷開導致進程結束(nohup,  setsid,  &, disown)

1、nohup 命令

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

nohup & 命令並不能從根本上解決ssh斷開問題。

1 [root@Searchsvc1 go-mysql-elasticsearch]# nohup tail -f nohup.out &
2 [1] 21509

pid所屬的父id為:21476

1 [root@Searchsvc1 go-mysql-elasticsearch]# ps -ef |grep tail 2 root     21509 21476 98 21:39 pts/1    00:01:17 tail -f nohup.out 3 root     21518 20971  0 21:40 pts/0    00:00:00 grep tail

通過 pstree  -p 查看線程樹可知它屬於ssh的一個子線程,所以關閉ssh的時候,會將其子線程hangup。

1   ├─sshd(1472)─┬─sshd(20967)───bash(20971)───pstree(21516) 2         │            └─sshd(21472)───bash(21476)───tail(21509)

 

2、 setsid 命令

我們換個角度思考,如果我們的進程不屬於接受 HUP 信號的終端的子進程,那么自然也就不會受到 HUP 信號的影響了。setsid 就能幫助我們做到這一點。讓我們先來看一下 setsid 的幫助信息。

1 [root@Searchsvc1 go-mysql-elasticsearch]# setsid tail -f nohup.out 2 [root@Searchsvc1 go-mysql-elasticsearch]# 2017/11/16 21:34:30 master.go:54: [info] save position (mysql-bin.000052, 98963482) 3 2017/11/16 21:35:13 master.go:54: [info] save position (mysql-bin.000052, 98966359)
setsid 命令會將結果信息輸出到控制台,並沒有從真正意義上將線程轉向后台執行
我們再來看下執行該命令后的進程的父pid:1 ,已經跟ssh已經沒有關系了。
1 init(1)─┬─abrtd(1572) 2         ├─acpid(1363) 3         ├─atd(1609) 4     
5         ├─sshd(1472)─┬─sshd(20967)───bash(20971)───pstree(21650) 6         │            └─sshd(21472)───bash(21476) 7         ├─tail(21645)

3、&命令,()命令

這里還有一個關於 subshell 的小技巧。我們知道,將一個或多個命名包含在“()”中就能讓這些命令在子 shell 中運行中,從而擴展出很多有趣的功能,我們現在要討論的就是其中之一。當我們將"&"也放入“()”內之后,我們就會發現所提交的作業並不在作業列表中,也就是說,是無法通過jobs來查看的。讓我們來看看為什么這樣就能躲過 HUP 信號的影響吧。

但用&能將進程轉向后台,但是

1 ├─sshd(1472)─┬─sshd(20967)───bash(20971)───pstree(21662) 2         │            └─sshd(21472)───bash(21476)───tail(21655)

()命令

1 [root@Searchsvc1 go-mysql-elasticsearch]# (tail -f nohup.out) 2 2017/11/16 21:57:38 master.go:54: [info] save position (mysql-bin.000052, 99185120)
1  ├─sshd(1472)─┬─sshd(20967)───bash(20971)───pstree(21664) 2         │            └─sshd(21472)───bash(21476)───tail(21663)

從上面可以看出&,()都會將結果信息輸出到控制台,而且轉向后台的線程會因為ssh的關閉而影響,但是執行(tail -f nohup.out &)卻能改變結果,進程將不再屬於ssh的子進程

1         ├─sshd(1472)─┬─sshd(20967)───bash(20971)───pstree(21685) 2         │            └─sshd(21472)───bash(21476) 3         ├─tail(21683)

 

4、disown命令

我們已經知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 HUP 信號的影響。但是如果我們未加任何處理就已經提交了命令,該如何補救才能讓它避免 HUP 信號的影響呢?

  • disown -h jobspec來使某個作業忽略HUP信號。
  • disown -ah 來使所有的作業都忽略HUP信號。
  • disown -rh 來使正在運行的作業忽略HUP信號。

需要注意的是,當使用過 disown 之后,會將把目標作業從作業列表中移除,我們將不能再使用jobs來查看它,但是依然能夠用ps -ef查找到它。

 

5、screen 命令

  • screen -dmS session name來建立一個處於斷開模式下的會話(並指定其會話名)。
  • screen -list 來列出所有會話。
  • screen -r session name來重新連接指定會話。
  • 用快捷鍵CTRL-a d 來暫時斷開當前會話。

 

 

6、PS命令

在ps命令中,“-T”選項可以開啟線程查看。下面的命令列出了由進程號為<pid>的進程創建的所有線程。

 ps -T -p <pid>

1 [root@Searchsvc1 go-mysql-elasticsearch]# ps -T -p 21813
2   PID  SPID TTY          TIME CMD

 

“SID”欄表示線程ID,而“CMD”欄則顯示了線程名稱。

7、 Top命令

top命令可以實時顯示各個線程情況。要在top輸出中開啟線程查看,請調用top命令的“-H”選項,該選項會列出所有Linux線程。在top運行時,你也可以通過按“H”鍵將線程查看模式切換為開或關。

1、 top -H

2、要讓top輸出某個特定進程<pid>並檢查該進程內運行的線程狀況:top -H -p <pid>。

 

Reference:

【1】

https://www.ibm.com/developerworks/cn/linux/l-cn-nohup/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM