http://hustwindmaple.spaces.live.com/blog/cns!130E9965613B9994!8732.entryGNU Screen zzGNU Screen -- MITBBS Linux版鎮版之寶
* 什麼是GNU Screen
常來我們版的,基本上就算沒有自己用過也聽說過screen的名字了,那麼到底什
麼是screen, 它又是幹什麼的呢?為什麼它能稱得上是我們的鎮版之寶?
screen的手冊上說了,screen是一個terminal multiplexer。但是對於普通人來
講,這個定義和沒有定義差不多。我覺得最通俗的解釋,應該說screen相當於文
本介面下面的一個desktop,就像GNOME, KDE之於X視窗系統。其次,screen還提
供類似於遠端桌面(freenx, vnc, 或者Windows下的remote desktop)的功能,
你可以在本地產生一個"案頭",然後通過網路重新連到這個"案頭",所有你開的
"視窗"都還在。從這一點上說,screen完全可以取代nohup協助你遠程跑長時間的
程式,比如說需要過夜計算的simulation之類。
* Screen的準系統
在我們談screen的準系統之前,我們來看看一個現代desktop,比如說gnome,
到底都為使用者提供了什麼。
首先,gnome提供了一個多視窗管理機制。以前這一塊由metacity提供,現在很多
情況下是由compiz fusion 3D視窗管理器管。無論是老土的metacity還是眩目的
compiz fusion,其實說穿了都不過是給使用者一個機制來管理多個同時啟動並執行圖形
化程式。廣而論之,X下面的virtual desktop也不過是這個機制的延伸。
其次,gnome提供了一個(或者多個)panel,這個panel上可以載入很多有用的插
件。其中最有用的是window list,顯示出你當前開啟的幾個應用程式的名字,然
後提供一個切換的方法。
第二有用的panel外掛程式大概就是system monitor吧,能夠顯示出系統當前的
loads, memory等等。有的人大概還喜歡在panel上面顯示時間,機器名等等資訊。
再接下來,gnome還提供了一些別的服務,比如說程式與程式間的copy/paste服務,
設定多語言編碼方式,鍵盤熱鍵設定,必要的時候把螢幕鎖上等等。
我們很快就能看到,以上說的這些功能,都有screen下的對應。當然,gnome是個
龐然大物,裡頭還有無數應用程式,就是那些以g開頭的無數程式。但這些嚴格的
講並不是一個案頭系統的一部分。甚至連nautilus嚴格的講也不能算是desktop裡
頭不可分割的一部分。這些應用程式其實很多在文本介面下也有對應物,只不過
不由screen負責而已。我會在本文裡頭附帶稍微介紹一下一些文字模式下的應用
程式。
* Screen的基本操作
** 第一次啟動screen
每一個screen進程本身代表一個session. 最簡單的方法是在一個終端下直接輸入
screen然後斷行符號。這時你會看到一個很簡陋的greeting介面,然後你隨便按一個
空格它就消失了,剩下的就是普通的shell提示符,好像什麼都沒發生過。你可以
運行一些標準shell指令,比如說ls,你會發現這個shell和別的shell沒有任何不
同。
運行如下命令
screen -ls
你會發現它告訴你有一個screen在跑:
$ screen -ls
There is a screen on:
8671.pts-1.inferno (Attached)
1 Socket in /var/run/screen/S-qiuxing.
現在你輸入Ctrl-a, 然後單個字母w,會發現左下角出現一個提示,比如說:
0*$ bash
現在再按Ctrl-a然後d,這時你開頭運行命令出現的那些文字都不見了。我們現在再來
跑一次screen -ls:
$ screen -ls
There is a screen on:
8671.pts-1.inferno (Detached)
1 Socket in /var/run/screen/S-qiuxing
什麼都沒變除了狀態由Attached變成了Detached。
現在你把你剛剛用的xterm關掉,重開一個xterm,或者有條件的話換一部電腦,
ssh到你的第一部機器,然後輸入screen -r。你看見了什嗎?是不是之前的那些
文字都又回來了?
其實真正發生的是這麼一個過程:screen建立了一個socket(一般是在
/var/run/screen/下面),把它偽裝成為一個虛擬文本終端(pty device)來充當
標準輸入輸出裝置,然後調用了一個shell 程式讓它運行在這個文本終端(其實
是個socket)上。當你從一個xterm裡頭detach掉了screen,screen下啟動並執行程式
不會直接退出,因為它們用的標準輸入輸入裝置已經不是你的xterm(下面跑的那
個shell)所相關的那個虛擬文本終端,而是一個socket了。
** 管理session
一般來說,我們不會裸起一個screen. 好的practice是每次新開一個screen,都
給它取一個好記的名字:
screen -S a_name
下次再用screen -ls的時候就會發現它有一個名字了(就是隨機數後面的那一部
分)。
以下為和管理session有關的命令:
- 檢查有多少screen session和它們的狀態用screen -ls
- detach一個正在跑的session用Ctrl-a d
- reattach這個session用screen -r,
- 如果有多個detached的session, 而我們又想attach到某一個的話,就用screen
-r a_name
- 在一個正在跑的session裡頭改名字: 先按Ctrl-a, 然後按冒號:, 出來一個類
似vi的輸入命令的介面,在裡頭運行這個內部命令:sessionname a_name
一個很常見的情況:有時我們需要強制reattach到一個attached session,比如
說忘記detach了,或者是ssh的時候網路斷線了. 這個命令是: screen -RD
a_name. 事實上它的實現是先給a_name session發出一個detach指令,然後在發
出一個attach指令。
** 管理視窗
- 產生一個新的視窗: Ctrl-a c。這個新的視窗跑的是你的shell。
- 產生一個新的視窗,並且讓它跑某個指定的程式: Ctrl-a :, 然後輸入:
screen -t <name> <n> <command> 其中<name>是視窗的名字,<n>是視窗號,
<command>是指定的程式。這個命令主要是在設定檔裡頭用。
- 關閉一個視窗: 退出這個視窗的程式,則視窗自動關閉
- 在無法退出某個程式的時候強制關閉一個視窗: Ctrl-a K
- 視窗列表: Ctrl-a w
- 視窗切換:
1. Ctrl-a ", 出現一個菜單可以選擇
2. Ctrl-a <n>, <n>是從0到9的視窗ID,這個命令直接切換到第<n>號視窗
3. Ctrl-a SPACE, 下一個視窗
4. Ctrl-a BACKSPACE, 前一個視窗
5. Ctrl-a Ctrl-a, 在當前和前一個視窗之間轉換,相當於Alt-Tab的功能
- 視窗改名: Ctrl-a A
** 分屏
- 上下分成兩個地區: Ctrl-a S (相當於emacs裡的C-x 2
- 在兩個地區裡頭切換: Ctrl-a TAB
- 合并兩個地區: Ctrl-a Q (相當於emacs裡的C-x 1), Ctrl-a X (相當於
emacs裡頭的C-x 0)
** copy/paste
正常模式下screen把所有的不以Ctrl-a開頭的命令都完全透明地pass給視窗裡
頭的程式了。其實screen還有一個copy/paste模式,進入這個模式後screen的行
為就更像一個text editor(vi),你可以copy/paste,也可以上下移動(相當於
scroll window)。
- 進入copy/paste mode: Ctrl-a ESC或者Ctrl-a [.
- 在c/p mode下移動游標: 上下左右箭頭,pgup/pgdown等。vi的hjkl,BE,/?等
等也都work
- Set mark: SPACE (類似emacs裡面的Ctrl-SPACE)
- 兩個mark裡的內容自動進入screen的c/p buffer, 並且退出c/p mode。
- 這個c/p buffer還可以用檔案寫出來: Ctrl-a >
在正常模式下,Ctrl-a ]能夠paste剛剛選中的內容。
** 其它有用功能/注意事項
第一重要的注意事項: 不要亂按Ctrl-a s. 它會鎖死你的shell。不過不小心碰
到了也別怕,再按一下Ctrl-a q,你的shell就活過來了。
第二重要的事情: 我習慣了在shell/emacs裡用Ctrl-a而不是Home跳到句首。可
是現在Ctrl-a被screen佔用了。那麼,我們怎麼輸入一個Ctrl-a? 答案: Ctrl-a
再加字母a.
推論: 如果在一個screen裡頭不小心attach了另外一個screen怎麼辦? 用Ctr-a
a d來detach裡頭的那個screen.
- 查看系統時間等資訊: Ctrl-a t
- 查看screen本身的資訊: Ctrl-a v
- 鎖住螢幕: Ctrl-a x
- 清理螢幕: Ctrl-a l
- 有時候screen會顯示一些資訊,想要顯示上一次顯示的提示內容的話:
Ctrl-a m
- 給當前視窗錄影(產生一個log,記錄所有的資訊): Ctrl-a H
- 使用visual bell: Ctrl-a Ctrl-g
* 設定檔
screen的基本設定檔是~/.screenrc(使用者目錄下的一個隱藏檔案)。事實上在
這裡控制的screen參數都可以在一個正在跑的screen裡面通過進入命令列模式
(Ctrl-a :),輸入相關命令來實現。但寫設定檔可以省不少重複性的工作。
啟動screen時有一個"-c"的參數來使用任何一個指定檔案作為設定檔。比如:
screen -c .screenrc2
附錄裡有一個screenrc檔案例子,裡頭詳細的注釋了每一行是幹什麼的。
* 進階用法
** 關注某個視窗
有時候我們可能開了一個視窗來跑一個要跑很久的程式,又或者那個視窗跑的是
pine/mutt,但我們在另外一個視窗幹活。絕大多數時候第一個視窗都不會有任何
資訊,但假設出現了變化比如說程式跑完了或者收到了新的email,我們也希望能
夠在幹活的當前視窗得到一個提示。
還有另外一種相反的情況,比如說編譯一個大程式,不斷的會出各種資訊。但如
果不出了,那就說明編譯完了(或者錯了),這時候我們也希望得到通知。這個
功能大約對於Gentoo使用者來說是最有用的.
這些都可以通過開啟/關閉monitoring來實現。
- Ctrl-a M. 這樣當前視窗如果出現變化,系統會通過message來通知你
- Ctrl-a _. 正好是上面的反面,如果當前視窗15秒都沒動靜了,則screen會發
一個msg.
** caption/hardstatus line
之前我提到過screen可以實作類別似於gnome panel的功能。這個功能在screen裡面
叫做caption line或者hardstatus line。它的配置看起來比較複雜,但一旦搞明
白了你就可以用它幹很多很cool的事情。一個類比是配置bash的提示符,也是屬
於不大好配置但很強大的東西。
我先舉一個簡單的例子吧:
caption always "%{+b Yk}%w"
hardstatus alwayslastline "Host: %H Load: %l "
它的效果是出現了兩條panel, 第一條叫做caption line, 裡頭的內容是帶顏色的
視窗資訊, 第二條是hardstatus line, 裡頭有host和system load的資訊。
在"%{+b Yk}%w"裡頭,%是escape sequence,+b是指粗體,Yk指的是亮黃(Y)字型,
配黑色(k)背景,%w是視窗號/名字。hardstatus bar裡面,%H是hostname, %l是
系統load(和top裡頭顯示的一樣),其他就是一般的字元。
下面是一個比較複雜的hardstatus line配置, 視覺效果比單純的%w要好:
hardstatus alwayslastline '%{Yk}%-w%{.Yk}%n %t%{-}%+w %=%{.w}'
更多的色彩,資訊,請參閱screen manual裡頭關於string escapes那一章。
** Panel外掛程式
雖然screen提供了很多string escapes, 但它們還是不可能滿足所有人所有的需
要。比如說我自己就想知道系統使用了多少記憶體,有的人可能還想查看有沒有新
郵件,等等。在gnome panel裡頭,這些都是通過panel外掛程式來實現的。在screen
的caption/hardstatus line裡也有一個類似的機制,讓你把任何一個指定的程式
的output放在panel上。
一個簡單的例子:
backtick 1 5 5 uptime
hardstatus alwayslastline "%1`"
解釋一下:backtick 1 5 5 uptime的意思是定義外部命令uptime的標準輸出作為
一個string escape, ID為1. 一次顯示5秒鐘,5秒鐘之後重新運行一次。
比較複雜的例子(這也是我自己在用的screenrc):
backtick 1 5 5 /home/qiuxing/bin/my_sysload1
backtick 2 5 5 /home/qiuxing/bin/my_free
hardstatus string '%{Yk}%-w%{.Yk}%n %t%{-}%+w %=%{.w} %{.Yr}%1` %{.Yb}%2`M %
{kY}%C'
其中my_sysload1和my_free的內容如下:
my_sysload1:
#!/bin/bash
cat /proc/loadavg | cut -d" " -f1
my_free:
free -m | tail -n 2 | head -n 1 | cut -c27-29
** 256色
比較新的screen支援256色。如果自己編譯,記得在編譯的時候開啟這個選項。
Feisty和之前的Ubuntu下的screen沒有加這個編譯選項,但在Gutsy裡這個選項已
經有了。我知道的支援256色的程式有vi/emacs/elinks。如果你知道別的文本模
式程式支援256色,請務必讓我知道。
如果你知道你的screen支援256色,請在.screenrc裡頭加入這麼幾句:
term xterm-256color
attrcolor b ".I"
termcapinfo xterm-256color 'Co#256:AB=/E[48;5;%dm:AF=/E[38;5;%dm'
defbce "on"
其中第一句讓screen偽裝成一個xterm-256color,第二句讓screen使用bold字型,
第三句告訴screen怎麼定義前景背景等資訊,最後一句是讓screen用背景色來
erase text。
另外要確認一下你的系統上的確有xterm-256color這個term的資訊。在Ubuntu裡,
這個庫叫做ncurses-term。
** X/滑鼠支援
有一些文本程式也支援滑鼠(emacs, elinks, w3m),有的甚至還支援inline
picture display(w3m)。screen對於這些都支援得很好。只要記住遠端連線的時
候開啟X11 forwarding開關(ssh -X),另外要檢查一下shell變數DISPLAY是不
是設定對了(本地顯示應該是:0.0,遠程一般是:10.0之類的東西)。
** 編碼轉換
screen還有一個鮮為人知的功能:實現編碼轉換。比如說mrxvt只能支援gbk,但
不能支援unicode。可是我的中文檔案都是unicode編碼的。這時就可以通過
screen來實現編碼轉換:
encoding GBK UTF-8
只要在一個支援unicode的terminal裡頭產生一個screen session,detach之,下
次在一個編碼為zh_CN.gbk的mrxvt裡頭reattach上這個session,所有的
zh_CN.utf8編碼的中文文字就會自動轉換為gbk格式。
** 多使用者支援
screen還可以支援多使用者。也就是說一個使用者產生了一個session,然後讓guest
來參與。具體的做法是先讓screen變成一個setuid root的程式,然後在
screenrc裡頭允許另外一個使用者串連。
如果你用過這個功能就會發現它相當的cool。但因為有一定的security concern,
我就不寫太詳細了。真要想用的話請參照這個Gentoo howto:
http://gentoo-wiki.com/HOWTO_Snoop_terminal_session#Screen
* 附錄
** screenrc檔案範例
# 和256色相關的配置
term xterm-256color
attrcolor b ".I"
termcapinfo xterm-256color 'Co#256:AB=/E[48;5;%dm:AF=/E[38;5;%dm'
defbce "on"
# 編碼轉換
encoding GBK UTF-8
# 使用visual bell
vbell on
# 斷線的時候自動detach
autodetach on
# 不要出來那個煩人的greeting
startup_message off
# make the shell in every window a login shell
# 意思是會去執行~/.bash_profile
shell -$SHELL
# 在copy/paste模式下可以回溯到5000行的曆史
defscrollback 5000
#remove some stupid / dangerous key bindings
bind k
bind ^k
bind .
bind ^/
bind //
bind ^h
bind h
#make them better
bind 'K' kill
bind 'I' login on
bind 'O' login off
bind '}' history
# default windows
screen -t work 0
screen -t shell 1
screen -t su 3 sudo su -
screen -t others 4
chdir /home/qiuxing/Documents/writing/linux
screen -t notes 5
chdir
screen -t mutt 6 mutt
select 0
# hardstatus line hack
backtick 1 5 5 /home/xqiu/bin/my_sysload1
backtick 2 5 5 /home/xqiu/bin/my_free
hardstatus alwayslastline '%{Yk}%-w%{.Yk}%n %t%{-}%+w %=%{.w} %{.Yr}%1` %{.
Yb}%2`M %{kY}%C'
** 常用文字模式程式
- 檔案管理工具:
1. bash
2. mc (midnight commander)
- 系統資源管理
1. top
2. htop
3. ps
- 文本編輯: emacs -nw, vi, nano, ...
- 網路瀏覽器: w3m(中文支援很好), elinks
- 聊天:
1. finch. 這個是pidgin/gaim的文字模式, 唯一支援QQ的text mode程式
2. centericq 很早以前用過,功能也很強大
3. irssi 最好的IRC聊天室client
4. irssi + bitlbee 如果你用這個組合,你就是真正的chat geek了!
- 郵件/新聞群組
1. mutt
2. pine
3. gnus
- 檔案傳輸
1. lftp (支援很多協議包括sftp, www)
2. wget
3. rsync
4. unison
- 科學運算 R, octave, maxima, python (scipy), ...
- 網路調試
1. tcpdump
2. nmap
3. netcat
- 音樂 mpg321, mplayer, 還有一些比較複雜的比如說cplay, moc等。
- Bittorrent: rtorrent
** 更多資訊
最簡單的入門:http://blogamundo.net/code/screen/
複雜一點的:http://gentoo-wiki.com/TIP_Using_screen
當然最全的資訊還是screen user's manual:
http://www.delorie.com/gnu/docs/screen/screen_toc.html