命令行是一種強大的工具,但是它有一個嚴重的缺點:如果 shell 停止了,您的工作也就停止了。要想讓 shell 和您的工作保持活動狀態(甚至是跨多個會話和中斷的連接),可以使用 GNU Screen 作為控制台的窗口系統。
哈利波特有魔杖,雷神托爾有金色的巨錘,Buckethead 有斧子,但是這些武器與 QWERTY 鍵盤相比只是小兒科。只需在命令行上敲幾下,就可以啟動網站、招募軍團或擊敗可怕的火龍。
但是,QWERTY 鍵盤有一個嚴重的缺點:它很容易發生連接中斷。電話線上的噪音、無線連接中斷或者網路超時都可能導致遠程 shell 中斷。如果您已經在某個工作(比如調試一個應用程序)上花費了好幾小時,而一下子就丟失了所有成果,一定會很沮喪的。
不過這種災難是可以避免的。使用 GNU Screen 就可以了。Screen 可以在一個控制台(即與主機物理連接的啞終端)、xterm 窗口或 Secure Shell (SSH) 登錄 shell 中創建和管理多個 shell 窗口。可以從一個 shell 窗口迅速切換到另一個窗口,可以離開正在運行的 shell 並在任何時候重新連接。實際上,Screen 提供許多虛擬化的控制台。
圖 1 到圖 5 展示 Screen 的特性和操作。看一下 圖 1,這裡假設用戶已經使用 SSH 登錄到一台遠程主機。最初,在本地主機(比如您的筆記本或桌面計算機)上有一個本地 shell 和一個遠程 shell。通常,使用遠程 shell 在遠程主機上運行命令;輸出經過加密之後通過 SSH 連接發送到本地 shell。(在各張圖中,用藍色表示當前可見的 shell 輸出)。但是,如果本地 shell 或遠程 shell 或它們之間的連接中斷了,遠程 shell 就會終止,您的工作成果就會丟失。
圖 2 顯示在遠程主機上啟動 Screen 之後的情況。Screen 實用程序啟動,進而啟動一個新的 shell 窗口 A,可以在此窗口中運行命令。A 的輸出是可見的(由藍色表示);這個 shell 的輸出經過 Screen,再經過遠程登錄 shell,最後通過 SSH 到達本地登錄 shell。
Screen 本身並不 “露面”;它是一個代理,其作用是在它管理的正在運行的可用窗口中做出選擇。在任何時候,Screen 只能顯示一個窗口的輸出。可以把 Screen 看作虛擬的鍵盤-視頻-滑鼠 (KVM) 開關。
但是,也可以斷開與 Screen 的連接,見 圖 3。Screen 代理仍然存在,它控制的所有窗口也還存在,但是與 Screen 的連接臨時切斷了,這會讓用戶返回到遠程登錄 shell。
圖 4 顯示一種可能出現的情況。已經重新建立了到 Screen 的連接,還創建了另外兩個窗口(B 和 C)。窗口 A 和 B 繼續運行 shell 和所有附屬作業,但是只有 C 的輸出是可見的。當然,可以在窗口之間切換以監視各個作業的狀態。
最後,圖 5 顯示中斷與 Screen 的連接並終止遠程登錄 shell 的情況。Screen 和它的窗口仍然存在。可以重新登錄並連接 Screen(並通過 Screen 代理連接到它的窗口),繼續您的工作。
如果您常常要訪問遠程伺服器以執行維護或開發軟體,那麼 GNU Screen 是必不可少的工具。
構建並安裝 Screen
Screen 的最初版本早在 10 多年前就發布了,所以您的系統上很可能有這個實用程序(通常名為 /usr/bin/screen)。但是,如果系統上沒有 Screen,也很容易通過發行版的包管理器安裝它。例如,如果您使用 Debian Linux® 的變體(比如 Ubuntu),那麼可以用 apt-get 簡便地安裝 Screen:
$ sudo apt-get install screen |
另外,如果您喜歡從源代碼構建軟體,可以訪問 GNU Screen 項目頁面(見 參考資料 中的鏈接)並下載最新的代碼包。在撰寫本文時,Screen 的最新版本是 4.0.3,於 2008 年 8 月發布。下載並提取代碼,進入生成的源代碼目錄,然後依次運行 ./configure、make 和 sudo make install:
$ wget http://ftp.gnu.org/gnu/screen/screen-4.0.3.tar.gz $ tar xzf tar xzf screen-4.0.3.tar.gz $ cd screen-4.0.3 $ ./configure this is screen version 4.0.3 ... $ make CPP="gcc -E " srcdir=. sh ./osdef.sh ... $ sudo make install ... You may also want to install ./etc/etcscreenrc in /usr/etc/screenrc. $ sudo cp ./etc/etcscreenrc /usr/etc/screenrc |
Screen 現在就安裝好了,可以使用了。輸入 man screen 查看 Screen 的手冊頁。
開始使用 Screen
啟動 Screen。在出現許可協議消息時,按 Return;現在應該會看到一個新的登錄 shell 提示。(在下面的清單中,在每個 shell 提示前面人為地添加一個昵稱,以此區分各個 shell 實例並與圖 1 到圖 5 聯繫起來)。
Local $ ssh remote.example.com Last login: Sun Dec 21 17:23:16 2008 from local.example.com Remote $ hostname remote.example.com Remote $ screen A $ top |
現在處於 圖 2 所示的狀態。一個 Screen 會話正在運行(儘管看不到),窗口 A 處於活動狀態,它正在運行系統監視器 top,每隔幾秒刷新一次系統性能信息。
為了臨時斷開與 Screen 會話及其所有窗口的連接,按 Ctrl-a,然後按 d(小寫的字母 D,代表 “detach”)。Ctrl-a 是 Screen 命令的前綴,d 是用於斷開連接的命令。現在處於 圖 3 所示的狀態。Screen 會話和窗口 A 仍然存在。可以通過運行 screen -list 確認這一點:
$ screen -list There is a screen on: 21020.pts-2.remote (Detached) 1 Socket in /tmp/screens/S-strike. |
screen -list 命令顯示所有可用的 Screen 會話。(順便說一句,可以同時運行多個 Screen 會話,每個會話有一組同時運行的窗口。圖 6 顯示這種情況。每個 Screen 實例跟蹤它自己的當前窗口。稍後會提供一些關於 Screen 的高級用法的提示)。編號為 21020 的會話已經斷開連接並相應地加上了標誌。因為只有一個 Screen 會話,所以可以直接用 screen -r 重新連接它。由於運行了 Screen,top 會一直運行。
為了進入 圖 4 所示的狀態,重新連接當前會話,然後按 Ctrl-a,然後按 c(小寫的字母 C,代表 “create”)創建一個新窗口。接下來,按 Ctrl-a,然後再次按 c。現在,Screen 會話管理三個窗口。
按 Ctrl-a,然後在當前窗口中按雙引號鍵("),就可以看到會話中可用窗口的列表:
Num Name Flags 0 bash $ 1 bash $ 2 bash $ |
在默認情況下,窗口的名稱取自它啟動的第一個命令(通常是一個 shell)。因此,在上面的列表中有三個 bash 窗口。可以用箭頭鍵在窗口列表中上下移動;只需按回車即可選擇窗口。
終止當前窗口的方法是,在窗口的 shell 提示上輸入 exit,或者按鍵盤快捷鍵 Ctrl-a,然後按 k(小寫的字母 K,代表 “kill”)。如果使用后一種方法,那麼在窗口底部會出現一個警告,要求您確認要殺死此窗口。按 y(小寫的字母 Y,代表 “yes”)確認,或按 n(小寫的字母 N,代表 “no”)拒絕。如果殺死一個 Screen 會話中運行的所有窗口,屏幕命令就會輸出一個消息並終止:
Remote $ screen ... Create and manipulate windows ... ... Exit from all windows... [screen is terminating] Remote $ screen -list No Sockets found in /tmp/uscreens/S-supergiantrobot. |
如果殺死了所有打開的窗口,那麼 screen -list 命令輸出 No sockets...,表示沒有 Screen 會話可用。
更智能化的屏幕
到目前為止,已經看到了如何在一個 Screen 會話中創建多個窗口。只需這麼做,就足以確保命令行工作不會丟失。
但是坦率地說,由於同時運行多個看起來相同的窗口,管理時可能引起混亂。最好能夠輕鬆地區分窗口,而不需要逐一打開每個窗口。如果在斷開連接和重新連接之間間隔的時間比較長的話,這種特性尤其有意義。
實際上,Screen 提供了許多選項和工具來幫助定製您的工作環境。可以給每個窗口指定名稱,還可以在每個窗口的底部顯示一個狀態欄以幫助區分窗口。
指定窗口名稱的方法是,激活窗口,按 Ctrl-a A(大寫的字母 A,代表 “Annotate”),根據需要按 Backspace 刪除現有的名稱,然後在提示上輸入一個有意義的名稱:
Num Name Flags 0 Window A $ 1 Window B $ 2 Window C $ |
在 圖 7 中,窗口的標題被設置為 Window A。窗口的昵稱不必是惟一的。
可以使用狀態欄在視覺上進一步區分各個窗口。啟動您喜歡的文本編輯器,在主目錄中創建包含以下代碼的 .screenrc 文件:
hardstatus on hardstatus alwayslastline hardstatus string "%{.bW}%-w%{.rW}%n %t%{-}%+w %=%{..G} %H %{..Y} %m/%d %C%a " |
創建這樣的 .screenrc 配置文件之後,每個新窗口就會顯示狀態欄,其中包含窗口的名稱。圖 8 顯示一個包含狀態欄的窗口。
有幫助的 Screen 提示
Screen 的特性非常多,無法在這裡一一介紹。下面給出一些提示並介紹幾個比較有用的選項,幫助您更順暢地使用 Screen:
Local $ ssh remote.example.com Remote $ screen -t ghost Ghost $ screen -t new New $ ... Press Control-a d to detach... Remote $ screen -r -p ghost Ghost $ |
Screen 的高級用法
正如前面提到的,可以創建多個同時運行的 Screen 會話,每個會話可以管理一系列窗口。每個會話有一個惟一標識符;使用 screen -list 列出可用的所有會話。與窗口一樣,可以給會話指定名稱以便引用它。使用 screen -S label 給新會話分配標籤。
共享是 Screen 會話的最佳用法之一。如果允許,可以連接現有的會話並在此會話的任何窗口中與其他用戶協作。甚至可以獨立地切換到會話中的另一個窗口。如果您與其他用戶在同一窗口中,輸入或顯示的任何內容都會反映給所有夥伴。我們來試一下:
-x 選項指定多用戶模式;-p one 直接連接到 one 窗口。應該會馬上看到與另一個登錄會話相同的輸出,見 圖 9。
在每個登錄窗口中,運行 UNIX® 命令產生輸出,按 Screen 快捷鍵在共享的會話中的窗口之間切換並查看結果。
結束語
要想進一步掌握 Screen,可以研究一下多屏幕模式,學習如何用老式的鎖防止對各個窗口的訪問。
Screen 是一個很實用的工具,它對於在命令行上執行的任何工作都很有價值。實際上,一旦掌握了它,您就會覺得離不開它了。(責任編輯:A6)
[火星人 ] 對話 UNIX: 使用 Screen 創建並管理多個 shell已經有558次圍觀