使用 screen 管理你的遠程會話

你是否是常常須要 SSH 或者 telent 遠程登陸到 Linux 服務器?你是否是常常爲一些長時間運行的任務而頭疼,好比系統備份、ftp 傳輸等等。一般狀況下咱們都是爲每個這樣的任務開一個遠程終端窗口,由於他們執行的時間太長了。必須等待它執行完畢,在此期間可不能關掉窗口或者斷開鏈接,不然這個任務就會被殺掉,一切半途而廢了。html

讓咱們來看看爲何關掉窗口/斷開鏈接會使得正在運行的程序死掉。linux

在Linux/Unix中,有這樣幾個概念:shell

  • 進程組(process group):一個或多個進程的集合,每個進程組有惟一一個進程組ID,即進程組長進程的ID。
  • 會話期(session):一個或多個進程組的集合,有惟一一個會話期首進程(session leader)。會話期ID爲首進程的ID。
  • 會話期能夠有一個單獨的控制終端(controlling terminal)。與控制終端鏈接的會話期首進程叫作控制進程(controlling process)。當前與終端交互的進程稱爲前臺進程組。其他進程組稱爲後臺進程組。

根據POSIX.1定義:bash

  • 掛斷信號(SIGHUP)默認的動做是終止程序。
  • 當終端接口檢測到網絡鏈接斷開,將掛斷信號發送給控制進程(會話期首進程)。
  • 若是會話期首進程終止,則該信號發送到該會話期前臺進程組。
  • 一個進程退出致使一個孤兒進程組中產生時,若是任意一個孤兒進程組進程處於STOP狀態,發送SIGHUP和SIGCONT信號到該進程組中全部進程。

所以當網絡斷開或終端窗口關閉後,控制進程收到SIGHUP信號退出,會致使該會話期內其餘進程退出。服務器

咱們來看一個例子。打開兩個SSH終端窗口,在其中一個運行top命令。網絡

[root@tivf09 root]# top

在另外一個終端窗口,找到top的進程ID爲5180,其父進程ID爲5128,即登陸shell。session

[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命令能夠更清楚地看到這個關係:ssh

[root@tivf09 root]# pstree -H 5180|grep top
|-sshd-+-sshd---bash---top

使用ps-xj命令能夠看到,登陸shell(PID 5128)和top在同一個會話期,shell爲會話期首進程,所在進程組PGID爲5128,top所在進程組PGID爲5180,爲前臺進程組。socket

[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也被殺掉了。ide

[root@tivf09 root]# ps -ef|grep 5128
root     18699  3672  0 04:35 pts/2    00:00:00 grep 5128

若是咱們能夠忽略SIGHUP信號,關掉窗口應該就不會影響程序的運行了。nohup命令能夠達到這個目的,若是程序的標準輸出/標準錯誤是終端,nohup默認將其重定向到nohup.out文件。值得注意的是nohup命令只是使得程序忽略SIGHUP信號,還須要使用標記&把它放在後臺運行。

nohup <command> [argument…] &

雖然nohup很容易使用,但仍是比較「簡陋」的,對於簡單的命令可以應付過來,對於複雜的須要人機交互的任務就麻煩了。

其實咱們可使用一個更爲強大的實用程序screen。流行的Linux發行版(例如Red Hat Enterprise Linux 4)一般會自帶screen實用程序,若是沒有的話,能夠從GNU screen的官方網站下載。

[root@tivf06 ~]# rpm -qa|grep screen
xscreensaver-4.18-5.rhel4.11

簡單來講,Screen是一個能夠在多個進程之間多路複用一個物理終端的窗口管理器。Screen中有會話的概念,用戶能夠在一個screen會話中建立多個screen窗口,在每個screen窗口中就像操做一個真實的telnet/SSH鏈接窗口那樣。在screen中建立一個新的窗口有這樣幾種方式:

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

[root@tivf06 ~]# screen

Screen將建立一個執行shell的全屏窗口。你能夠執行任意shell程序,就像在ssh窗口中那樣。在該窗口中鍵入exit退出該窗口,若是這是該screen會話的惟一窗口,該screen會話退出,不然screen自動切換到前一個窗口。

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

[root@tivf06 ~]# 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文件:

[root@tivf06 ~]# screen vi /tmp/abc

以後咱們想暫時退出作點別的事情,好比出去散散步,那麼在screen窗口鍵入C-a d,Screen會給出detached提示:

暫時中斷會話

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

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

從新鏈接會話:

[root@tivf06 ~]# 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 [ 進入拷貝/回滾模式

使用鍵綁定C-a ?命令能夠看到, 默認的命令字符(Command key)爲C-a,轉義C-a(literal ^a)的字符爲a:

Screen 經常使用選項

由於screen把C-a看做是screen命令的開始,因此若是你想要screen窗口接收到C-a字符,就要輸入C-a a。Screen也容許你使用-e選項設置本身的命令字符和轉義字符,其格式爲:

-exy x爲命令字符,y爲轉義命令字符的字符

下面命令啓動的screen會話指定了命令字符爲C-t,轉義C-t的字符爲t,經過C-t ?命令能夠看到該變化。

[root@tivf18 root]# screen -e^tt

自定義命令字符和轉義字符

其餘經常使用的命令選項有:

-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,但刪掉那些沒法鏈接的會話

下例顯示當前有兩個處於detached狀態的screen會話,你可使用screen -r <screen_pid>從新鏈接上:

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

[root@tivf18 root]# screen –r 8736

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

[root@tivf18 root]# kill -9 8462
[root@tivf18 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.

[root@tivf18 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.

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

[root@tivf18 root]#

-d –m 選項是一對頗有意思的搭檔。他們啓動一個開始就處於斷開模式的會話。你能夠在隨後須要的時候鏈接上該會話。有時候這是一個頗有用的功能,好比咱們可使用它調試後臺程序。該選項一個更經常使用的搭配是:-dmS sessionname

啓動一個初始狀態斷開的screen會話:

[root@tivf06 tianq]# screen -dmS mygdb gdb execlp_test

鏈接該會話:

[root@tivf06 tianq]# screen -r mygdb

先來看看如何使用screen解決SIGHUP問題,好比如今咱們要ftp傳輸一個大文件。若是按老的辦法,SSH登陸到系統,直接ftp命令開始傳輸,以後。。若是網絡速度還能夠,恭喜你,不用等太長時間了;若是網絡很差,老老實實等着吧,只能傳輸完畢再斷開SSH鏈接了。讓咱們使用screen來試試。

SSH登陸到系統,在命令行鍵入screen。

[root@tivf18 root]# screen

在screen shell窗口中輸入ftp命令,登陸,開始傳輸。不肯意等了?OK,在窗口中鍵入C-a d:

管理你的遠程會話

而後。。退出SSH登陸?隨你怎樣,只要別殺掉screen會話。

是否是很方便?更進一步,其實咱們能夠利用screen這種功能來管理你的遠程會話,保存你全部的工做內容。你是否是每次登陸到系統都要開不少窗口,而後天天都要重複打開關閉這些窗口?讓screen來幫你「保存」吧,你只須要打開一個ssh窗口,建立須要的screen窗口,退出的時候C-a d「保存」你的工做,下次登陸後直接screen -r <screen_pid>就能夠了。

最好能給每一個窗口起一個名字,這樣好記些。使用C-a A給窗口起名字。使用C-a w能夠看到這些窗口名字,可能名字出現的位置不一樣。使用putty:

putty

使用telnet:

telnet

Screen提供了豐富強大的定製功能。你能夠在Screen的默認兩級配置文件/etc/screenrc和$HOME/.screenrc中指定更多,例如設定screen選項,定製綁定鍵,設定screen會話自啓動窗口,啓用多用戶模式,定製用戶訪問權限控制等等。若是你願意的話,也能夠本身指定screen配置文件。

以多用戶功能爲例,screen默認是以單用戶模式運行的,你須要在配置文件中指定multiuser on 來打開多用戶模式,經過acl*(acladd,acldel,aclchg...)命令,你能夠靈活配置其餘用戶訪問你的screen會話。更多配置文件內容請參考screen的man頁。

關於做者

田強,中國軟件開發中心 Tivoli 部門軟件工程師,負責 IBM 產品TMF(Tivoli Management Framework)的維護和客戶支持工做,熱愛 Linux。

原文地址:http://www.ibm.com/developerworks/cn/linux/l-cn-screen/

相關文章
相關標籤/搜索