如果想在關閉ssh連接配接後剛才啟動的程式繼續運作怎麼辦,可以使用nohup。但是如果要求第二天來的時候,一開ssh,還能檢視到昨天運作的程式的狀态,然後繼續工作,這時nohup是不行了,需要使用screen來達到這個目的。
nohup指令可以用來執行其他指令,并且忽略SIGHUP信号(run a command immune to hangups, with output to a non-tty。Run COMMAND, ignoring hangup signals.)當一個虛拟終端的網絡連接配接斷開時,作業系統向正在運作的程式發送SIGHUP信号(HUP = HangUP、挂斷),預設情況下這個信号将使程式退出。
一 nohup
問題1為什麼ssh一關閉,程式就不再運作了?
元兇:SIGHUP 信号
讓我們來看看為什麼關掉視窗/斷開連接配接會使得正在運作的程式死掉。
在Linux/Unix中,有這樣幾個概念:
程序組(process group):一個或多個程序的集合,每一個程序組有唯一一個程序組ID,即程序組長程序的ID。
會話期(session):一個或多個程序組的集合,有唯一一個會話期首程序(session leader)。會話期ID為首程序的ID。
會話期可以有一個單獨的控制終端(controlling terminal)。與控制終端連接配接的會話期首程序叫做控制程序(controlling process)。目前與終端互動的程序稱為前台程序組。其餘程序組稱為背景程序組。
根據POSIX.1定義:
挂斷信号(SIGHUP)預設的動作是終止程式。
當終端接口檢測到網絡連接配接斷開,将挂斷信号發送給控制程序(會話期首程序)。
如果會話期首程序終止,則該信号發送到該會話期前台程序組。
一個程序退出導緻一個孤兒程序組中産生時,如果任意一個孤兒程序組程序處于STOP狀态,發送SIGHUP和SIGCONT信号到該程序組中所有程序。
結論:是以當網絡斷開或終端視窗關閉後,也就是SSH斷開以後,控制程序收到SIGHUP信号退出,會導緻該會話期内其他程序退出。
簡而言之:就是ssh 打開以後,bash等都是他的子程式,一旦ssh關閉,系統将所有相關程序殺掉!! 導緻一旦ssh關閉,執行中的任務就取消了
例子:
我們來看一個例子。打開兩個SSH終端視窗,在其中一個運作top指令。
[root@tivf09 root]# top
在另一個終端視窗,找到top的程序ID為5180,其父程序ID為5128,即登入shell。
[root@tivf09 root]# ps -ef|grep top
root 5180 5128 0 01:03 pts/0 00:00:02 top
root 5857 3672 0 01:12 pts/2 00:00:00 grep top
使用pstree指令可以更清楚地看到這個關系:
[root@tivf09 root]# pstree -H 5180|grep top
|-sshd-+-sshd---bash---top
使用ps-xj指令可以看到,登入shell(PID 5128)和top在同一個會話期,shell為會話期首程序,所在程序組PGID為5128,top所在程序組PGID為5180,為前台程序組。
[root@tivf09 root]# ps -xj|grep 5128
5126 5128 5128 5128 pts/0 5180 S 0 0:00 -bash
5128 5180 5180 5128 pts/0 5180 S 0 0:50 top
3672 18095 18094 3672 pts/2 18094 S 0 0:00 grep 5128
關閉第一個SSH視窗,在另一個視窗中可以看到top也被殺掉了。
[root@tivf09 root]# ps -ef|grep 5128
root 18699 3672 0 04:35 pts/2 00:00:00 grep 5128
問題2 為什麼守護程式就算ssh 打開的,就算關閉ssh也不會影響其運作?
因為他們的程式特殊,比如httpd –k start運作這個以後,他不屬于sshd這個程序組 而是單獨的程序組,是以就算關閉了ssh,和他也沒有任何關系!
[root@CentOS5-4 ~]# pstree |grep http
|-httpd
[root@CentOS5-4 ~]# pstree |grep top
|-sshd-+-sshd---bash---top
結論:守護程序的啟動指令本身就是特殊的,和一般指令不同的,比如mysqld_safe 這樣的指令 一旦使用了 就是守護程序運作。是以想把一般程式改造為守護程式是不可能,
問題3 使用背景運作指令& 能否将程式擺脫ssh程序組控制呢 也就是ssh關閉,背景程式繼續運作?
我們做一個試驗: find / -name ‘*http*’ &
利用ctrl+d 登出以後 再進入系統 會不會看見這個指令再運作?
答案是 :指令被中止了!!
因為他依然屬于這個ssh程序組 就算加了&也無法擺脫!!
[root@CentOS5-4 ~]# pstree |grep find
|-sshd-+-sshd---bash---find
結論就是:隻要是ssh 打開執行的一般指令,不是守護程式,無論加不加&,一旦關閉ssh,系統就會用SIGHUP終止
問題4 nohup能解決的問題
但是為了能夠再登出以後 依然能背景運作,那麼我們就可以使用nohup這個指令,我們現在開始查找find / -name ‘*http*’ &
,并且希望在背景運作,
那麼就使用nohup:nohup find / -name "*httpd*"
此時預設地程式運作的輸出資訊放到目前檔案夾的 nohup.out 檔案中去
加不加&并不會影響這個指令 隻是讓程式 前台或者背景運作而已
二 screen
雖然nohup很容易使用,但還是比較“簡陋”的,對于簡單的指令能夠應付過來,對于複雜的需要人機互動的任務就麻煩了。
其實我們可以使用一個更為強大的實用程式screen。流行的Linux發行版(例如Red Hat Enterprise Linux 4)通常會自帶screen實用程式,如果沒有的話,可以從GNU screen的官方網站下載下傳。
1)使用
執行screen , 按任意鍵進入子界面;
我用ping指令開始執行,如果下班了,但是想關閉ssh以後ping繼續運作,那麼按ctrl+a 再按d 這樣暫停了子界面,會顯示[detached]的字樣,這時候 我回到了父界面;
用screen –ls檢視目前子界面的狀态 screen -ls
There is a screen on: 22292.pts-3.free (Detached)
1 Socket in /tmp/screens/S-root,這裡的22292其實是子界面的pid号;
如果回到子界面 用screen –r 22292,一下子彈到了ping 的子界面;
2)更多幫助
可以通過C-a(ctrl+a) ?來檢視所有的鍵綁定,常用的鍵綁定有:
C-a ?
顯示所有鍵綁定資訊
C-a w
顯示所有視窗清單
C-a C-a
切換到之前顯示的視窗
C-a c
建立一個新的運作shell的視窗并切換到該視窗
C-a n
切換到下一個視窗
C-a p
切換到前一個視窗(與C-a n相對)
C-a 0..9
切換到視窗0..9
C-a a
發送 C-a到目前視窗
C-a d
暫時斷開screen會話
C-a k
殺掉目前視窗
C-a [
進入拷貝/復原模式
其他常用選項:
-c file
使用配置檔案file,而不使用預設的$HOME/.screenrc
-d|-D [pid.tty.host]
不開啟新的screen會話,而是斷開其他正在運作的screen會話
-h num
指定曆史復原緩沖區大小為num行
-list|-ls
列出現有screen會話,格式為pid.tty.host
-d -m
啟動一個開始就處于斷開模式的會話
-r sessionowner/ [pid.tty.host]
重新連接配接一個斷開的會話。多使用者模式下連接配接到其他使用者screen會話需要指定sessionowner,需要setuid-root權限
-S sessionname
建立screen會話時為會話指定一個名字
-v
顯示screen版本資訊
-wipe [match]
同-list,但删掉那些無法連接配接的會話
參考:http://chlotte.blog.51cto.com/318402/556540
完!