我所知 screen 的奇技淫巧

Posted by 每特17劃 on 2024-05-12

我所知 screen 的奇技淫巧

近日在整理 $HOME 下的 dotfiles 時,遇到 .screenrc 的部分,覺得束之高閣可惜。決定稍作記錄與分享。

設定檔

分享設定檔 ~/.screenrc 如下:

caption always "%{= wk} %{= KY} [%n]%t @ %H %{-} %= %{= KR} %l %{-} | %{= KG} %Y-%m-%d %{-} "
hardstatus alwayslastline " %-Lw%{= Bw}%n%f %t%{-}%+Lw %=| %0c:%s "
termcapinfo xterm* ti@:te@

效果如下:

Pasted image 20240512140845.png

說明:

  • 最下面一行是由 hardstatus alwayslastline 設定的
    • 具備多分頁 tab 的效果
  • 倒數第二行則是 caption always 的設定
  • % 開頭的設定變數,可參考官方文件: Screen User’s Manual: String Escapes
  • termcapinfo 的那一行設定,則是應付滑鼠捲動。

總之,用了就會眼睛一亮。

因時日久遠,已忘了是從哪裏發掘這款設定的。原本印象是從 yungyuc 那裏學來的。但考古了一下,yungyuc 的 新生的 screenrc - Everyday Work 一文卻說是從我這裏學去的。這下我自己也懵了。

不過,看截圖應該是出自我的版本沒錯。記憶中,我先從某處得知了有 hardstatus, caption 的參數跟用法,但當時多是置底一行。因當時重度在 virtual console 的環境下作業,一時靈感之下拼湊出置底二行這樣的用法。

感謝有 yungyuc 當時的記錄與分享。

attach/detach

  • Ctrl-a + d, detach 目前所在的 session
  • screen -list , 列出目前的 sessions
  • screen -r <session> , resume 先前的 session
    • 若只有一個 session ,只要打 screen -r 即可

當 Terminal 掛掉時,該 Terminal 所在的程式也就跟着中斷了。用 screen 的好處就是,讓程式主體保持在背景執行,而允許前端的 Terminal session 隨時 attach/detach 。如此一來,即使不小心關掉了 Terminal (不論是 XWindow 當掉重啓),或是登出再登入,都能快速接續先前的狀態。

共用 session

  • screen -x <session>

這個功能在幾個情境下非常好用。我用過的情境如下:

其一, 在 XWindow 跟 Linux virtual console 頻繁切換使用。

我可能先在 XWindow 下編寫 window manager 的設定檔,同時在 console 下開好 ssh 連線預留後路。若是在調整 XWindow 設定有誤,則可退到 console 查看 log 、改設定跟重啓。萬一鍵盤鎖死無反應時,也還可從他處以 ssh 連回挽救。

其二, pair programming。

在緊湊討論 Linux 的 CLI, vim, debug 參數之時,最快的就是湊到對方的電腦前去看。但遇到要輸入時,就得共用鍵盤,不甚方便。加上每人各有自己偏好的熱鍵設定,實際操作往往卡卡的不甚流利。後來發現一技巧,就是開 ssh 連線到對方的電腦上,用 screen 的共用 session 功能。如此一來,雙方都能快速看到對方的 CLI ,也能直接改參數,起執行的 log 訊息也都無時差的同時 review ,整個效率提升很多。

此技法是從 HackingThursday 參加 2009 Yahoo Hacking Day 活動 時學來的,印象中是 Rex, Tsung, hychen 那一組發掘出來的。

順帶一提,後來出現有 tmate ,能節省開頭的 ssh 設定折騰,也非常推薦。不過,該工具的連線資料會過外部雲端,使用前需留意。

serial 工具

示例如下:

screen /dev/ttyUSB0 115200
screen -c /dev/null telnet -8 ptt.cc
Ctrl-a :encoding big5 utf-8

(註:參數說明可參閱 Screen User’s Manual: Window Types)

若說到現在還在用 screen 這工具,這絕對是最關鍵的理由。

這祕技其實是從 Thinker 那裏學來的。印象中好像是在請教他有無推薦的 serial 連線工具,例如: minicom, kermit, …之類的? 然後他就回說:

可以用 screen 啊!

這回答太出乎我的意料,因為 screen 在我心中的定位一直都是分割終端機畫面的工具,從沒想過用於 serial port 的操作,因而特別印象深刻。 長期使用後,發覺有諸多優點:

  • 十分穩定。之前用 minicom, 或其他工具,可能受 terminal 字元影響,而有閃退、中斷的問題。但印象中,screen 從以前用到現在,還沒有不正當當掉過。
  • 內建支援轉碼,例如: Ctrl-a :encoding big5 utf8
  • 畫面紀錄與紀錄檔功能。Ctrl-a h , Ctrl-a H
  • 不依賴 ncurses 或 prompt, 可和 expect/pexpect 搭配使用於automation scripts

唯一的缺點大概是要送出 Ctrl-a (screen的特殊鍵)時,要多跳脫一層。

解 lock

用 Terminal 久了,偶爾會遇到輸入被鎖住的情況,主要原因是Software flow control ,如下:

  • Ctrl-s, Ctrl-q, 是 Terminal 的 flow control on/off 熱鍵。
  • Ctrl-a + s, Ctrl-a + q 是 screen 的 flow control on/off 熱鍵。

當 screen 被鎖住時,可以就 Ctrl-a + qCtrl-q 反覆交叉按個數次,就可以解開了。

複製貼上

操作流程如下:

  • Ctrl-a + [ 進入 copy mode
  • 用方向鍵移動到開頭的位置,按下 ENTERSPACE
  • 用方向鍵移動到結尾的位置,再按下 ENTERSPACE,完成標定範圍的內容複製
  • 之後到要輸入的地方,按下 Ctrl-a + ] 進行貼上

因爲 XWindow terminal 一般的滑鼠複製貼上,遇有特殊字元或斷行偶爾會有問題,加上歷史記錄不一定夠長。相較之下, screen 的資料完整一些。所以,即使 Terminal 已經很方便了,遇到比較刁鑽的地方,還是不時會搭配 screen 來使用。

screen 裏的 screen

有時候會遇到一些情況是,在筆電裏開了 screen ,然後連到遠端主機,而遠端主機也開了 screen 。就成了 screen 裏的 screen 的情況。這時候按 Ctrl-a , Ctrl-a 的組合鍵,就會被本地端的 screen 先攔截,變成是切換本地端的 screen ,而不是切換遠端的 screen 。解法是改爲 Ctrl-a + a。 條列如下:

  • Ctrl-a + a , Ctrl-a ,切換遠端的 screen
  • Ctrl-a , Ctrl-a ,切換本地端的 screen

滑鼠 scroll

一般在 XWindow terminal 下開 screen 後, 畫面就框定住了,而沒能像一般 terminal 那樣 scroll up/down 。若是習慣用滑鼠 scroll 去看先前的畫面記錄。可以考慮在設定檔 ~/.screenrc 加上:

termcapinfo xterm* ti@:te@

重置邊框

若開 screen 時,是 80x24 的大小。而後在另一處改用 120x30 的 Terminal 連回時,會發現多了邊框。示意如下:

Pasted image 20240513000203.png

那如何改善呢?使用下述指令即可:

Ctrl-a :fit