同時使用多個命令列視窗常常讓人很頭痛
在 X Window 中工作,常常會開好幾個命令列視窗。在 Task Bar 上只看到一堆 xterm 或 rxvt,提供的資訊實在太少。常見
的情況是「咦,剛剛在 make install 的那個應用程式是編好了沒有?」然後不得不把每一個命令列視窗一一打開,直到在每一個都滿是文字的視
窗中,辨別出哪個是 make install 為止。為什麼通常開別的程式沒有這樣的問題?因為上至 browser、下至音樂播放程式,每一個都會
把現在正在做的事顯示在標題列上。要是命令列視窗也行該多好?
xterm/rxvt/PieTTY 其實是可以控制標題列顯示的內容的
上述程式及大多數他們的兄弟姐妹,可以用下列的 sequence 改變標題列的內容 (System V style):
\e]0;blah_blah\a
其中有兩個控制碼,\e 是 Escape (Ascii 10 進位 27,在此表示指令開始),\a 是 Bell (Ascii 的 7,在此表
示指令結束)。程式試圖向 terminal 輸出這串字時,xterm/rxvt/PieTTY 會察覺這是可接受的指令,接著依令把標題列內容換
為 blah_blah。其實 terminal 支援的指令不只這一個,不過不同的 terminal 支援的指令有可能不同,有興趣的可以參考
mrxvt 支援的指令 http://materm.sourceforge.net/wiki/Main/Documentation?action=download&upname=mrxvt_seq.txt
怎樣把這串字餵給 terminal?
最初我參考的是這頁中間的作法 http://materm.sourceforge.net/wiki/FAQ/Tips
但是在 FreeBSD 下怎麼也試不出來。後來才發覺依這頁的作法,\e 及 \a 並沒有如預期被轉換為控制碼,所以並未順利構成有效的指令。研究
了半天才知道,FreeBSD 預設的 tcsh 所提供的 echo 內建指令有兩種輸出模式,由環境變數 echo_style 所控制 (請
man csh,找 echo_style),分別為 bsd 模式及 sysv 模式 (以及同時支援兩者的 both 模式)。預設是前者,但只有
後者才會把 \e、\a 視做控制碼來輸出。因此只要:
set echo_style=both
echo -n "\e]0;blah_blah\a"
就可以把目前的標題列改為 blah_blah。
但是這樣還不夠好。我們的目標是希望標題列能顯示目前正在執行的指令不是嗎?
也就是說,我們必須在程式執行前,用上述方法把程式的名稱弄上標題列。從上述網頁的作法中我們有了必要的靈感。在 tcsh 中有幾個特別的
alias,上述網頁提及的 jobcmd 及 cwdcmd,就分別是 tcsh 在輸入一行指令按下 Enter 後、執行程式前會執行的命令,以
及目前的工作目錄改變時會執行的命令。也就是說:
set echo_style=both
alias jobcmd echo -n '"\e]0;"\!#:q "($cwd)\a"'
就會在每次執行一個命令前,都執行一次 echo -n 把這串魔咒送上標題列。!# 代表當前的指令,:q 代表取用這個命令的所有參數 (吃飽撐著
的請 man csh),於是標題列就會出現類似下面的東西:
make install (/usr/ports/sysutils/screen)
不過我個人對網頁的作法不是很滿意,因為只在 jobcmd 及 cwdcmd 這兩種時機更改標題列,就沒有辦法看出命令執行完沒有,因為上一個命令
執行完畢回到 prompt、直到下一個命令執行前,標題列都還會顯示上一個命令。這一點見人見智。我個人希望的是在程式執行完畢後,標題列能改回
csh 或是 terminal 之類的字眼,表示已回到 prompt 了。一個程式執行完後,shell 要做的事就是顯示 prompt,顯然這
是更改標題列最佳的機會。所以我採用的作法是:
set prompt="%{\e]0;csh (%/)\a%}%m:%/# "
在前面 %{ 到 %} 之間的部份會以 sysv 模式輸出,於是:
標題列: csh (/usr/ports/sysutils/screen)
prompt: foo:/usr/ports/sysutils/screen#
註: %m 會代換成 machine name,也就是 foo.hinet.net 中的 foo。%/ 會代換為目前的工作目錄
最後,這串魔咒落在看不懂的 terminal 眼裏,就會變成亂碼輸出。因此建議採用上述網頁的作法,用 if 敘述確認 terminal 是
xterm 或 rxvt 才動用魔咒。這些東西放進 ~/.cshrc 裏,就能自動在每一次開啟 terminal 時就自動執行。.cshrc
的參考內容請參考檔案區的 cshrc-example
註1
我後來覺得 cwdcmd 沒什麼用,所以只用了 jobcmd 及 prompt。我想只有在執行一個命令的期間工作目錄有改變,cwdcmd 才能
派得上用場。我猜要執行一些 interactive 的程式才有這種機會,想不出有什麼實用價值。
註2
xterm 和 rxvt 類的程式似乎大多管用,連 PieTTY 的標題列也管用,倒是讓我喜出望外。可惜 screen 好像不支援,一旦在
terminal 裏用了 screen,這個魔咒就破功了。要是有人有辦法在 screen 中使用,請麻煩回一下文分享一下 : )
註3
mrxvt 真的是好物,目前是我的 X Window 的主要 terminal。理由為:1. 支援 tab,所以開 N 個命令列,都是在同一個
視窗下,就像 Firefox 的 Tab browsing 一樣,很方便。上述方法會更改 tab 上的顯示,而 active 的那個 tab
的顯示,也會自動同步到標題列上,實在太完美了。 2. 吃資源超少。從 top 裏來看,別的 terminal 吃掉 50MB 以上的記憶體時,
這個才吃 3~5 MB。我沒用到的功能還有半透明顯示、支援背景圖、支援 TrueType 字型等等。不過有一個大缺點,就是目前的版本還不支援
utf-8 顯示 (但雙 byte CJK 似乎是支援的),未來的版本應該會支援。目前我是用 urxvt 來解決需要 utf-8 顯示的場合。