1. 程式人生 > >讓程式在遠端主機後臺執行 (&、nohuo、 screen)Linux 使用技巧

讓程式在遠端主機後臺執行 (&、nohuo、 screen)Linux 使用技巧

作為一個系統運維人員,你是不是經常需要 SSH 或者 telent 遠端登入到 Linux 伺服器?

你是不是經常為一些長時間執行的任務而頭疼,比如系統備份、ftp 傳輸等等。通常情況下

我們都是為每一個這樣的任務開一個遠端終端視窗,因為他們執行的時間太長了。必須等待

它執行完畢,在此期間可不能關掉視窗或者斷開連線,否則這個任務就會被殺掉,一切半途

而廢了

所以就上網找啊找,找到了一個從後臺一直執行某個程式的方法。

Unix/Linux下一般比如想讓某個程式在後臺執行,很多都是使用 & 在程式結尾來讓程式自動執行。

比如我們要執行mysql在後臺:

 /usr/local/mysql/bin/mysqld_safe --user=mysql &

但是加入我們很多程式並不象mysqld一樣做成守護程序,可能我們的程式只是普通程式而已,一般這種程式使用 & 結尾,

但是如果終端關閉,那麼程式也會被關閉。但是為了能夠後臺執行,那麼我們就可以使用nohup這個命令,nohup就是不

掛起的意思( n ohang up)。比如我們有個test.php需要在後臺執行,並且希望在後臺能夠定期執行,那麼就使用nohup:

  nohup /root/test.php &

值得注意的是nohup命令只是使得程式忽略SIGHUP訊號,還需要使用標記&

把它放在後臺執行。

nohup <command> [argument…] &

雖然nohup很容易使用,但還是比較“簡陋”的,對於簡單的命令能夠應付過來,對於複雜的需要人機互動的任務就麻煩了。


其實我們可以使用一個更為強大的實用程式screen。

簡單來說,Screen是一個可以在多個程序之間多路複用一個物理終端的視窗管理器。Screen中有會話的概念,使用者可以在一

個screen會話中建立多個screen視窗,在每一個screen視窗中就像操作一個真實的telnet/SSH連線視窗那樣。在screen中建立

一個新的視窗有這樣幾種方式:

1.直接在命令列鍵入screen命令

# screen

Screen將建立一個執行shell的全屏視窗。你可以執行任意shell程式,就像在ssh視窗中那樣。在該視窗中鍵入exit退出該視窗,

如果這是該screen會話的唯一視窗,該screen會話退出,否則screen自動切換到前一個視窗。


2.Screen命令後跟你要執行的程式。

# screen vi test.c

Screen建立一個執行vi test.c的單視窗會話,退出vi將退出該視窗/會話。


3.以上兩種方式都建立新的screen會話。我們還可以在一個已有screen會話中建立新的視窗。在當前screen視窗中鍵入C-a c

即Ctrl鍵+a鍵,之後再按下c鍵,screen 在該會話內生成一個新的視窗並切換到該視窗。

screen還有更高階的功能。你可以不中斷screen視窗中程式的執行而暫時斷開(detach)screen會話,並在隨後時間重新連線(attach)

該會話,重新控制各視窗中執行的程式。例如,我們開啟一個screen視窗編輯/tmp/abc檔案:

# screen vi /tmp/abc

之後我們想暫時退出做點別的事情,比如出去散散步,那麼在screen視窗鍵入C-a d,Screen會給出detached提示:

半個小時之後回來了,找到該screen會話:

[[email protected] ~]# screen -ls
There is a screen on:
        16582.pts-1.tivf06      (Detached)
1 Socket in /tmp/screens/S-root.

重新連線會話:

[[email protected] ~]# screen -r 16582

看看出現什麼了,太棒了,一切都在。繼續幹吧。

你可能注意到給screen傳送命令使用了特殊的鍵組合C-a。這是因為我們在鍵盤上鍵入的資訊是直接傳送給當前screen視窗,

必須用其他方式向screen視窗管理器發出命令,預設情況下,screen接收以C-a開始的命令。這種命令形式在screen中叫做鍵繫結

(key binding),C-a叫做命令字元(command character)。

可以通過C-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 [ 進入拷貝/回滾模式

下例顯示當前有兩個處於detached狀態的screen會話,你可以使用screen -r <screen_pid>重新連線上

[[email protected] root]# screen –ls
There are screens on:
        8736.pts-1.tivf18       (Detached)
        8462.pts-0.tivf18       (Detached)
2 Sockets in /root/.screen.

[[email protected] root]# screen –r 8736

如果由於某種原因其中一個會話死掉了(例如人為殺掉該會話),這時screen -list會顯示該會話為dead狀態。使用screen -wipe命令清除該會話:

[[email protected] root]# kill -9 8462
[[email protected] root]# screen -ls  
There are screens on:
        8736.pts-1.tivf18       (Detached)
        8462.pts-0.tivf18       (Dead ???)
Remove dead screens with 'screen -wipe'.
2 Sockets in /root/.screen.

[[email protected] root]# screen -wipe
There are screens on:
8736.pts-1.tivf18 (Detached)
8462.pts-0.tivf18 (Removed)
1 socket wiped out.
1 Socket in /root/.screen.

[[email protected] root]# screen -ls
There is a screen on:
8736.pts-1.tivf18 (Detached)
1 Socket in /root/.screen.

[[email protected] root]#


Reference:

http://www.ibm.com/developerworks/cn/linux/l-cn-screen/