1月32010

俺の .screenrc が火を吹くぜ

shyouhei:

たまにはこういう生産性のない話題もいいよね!

さて、まあおまえらも GNU Screen くらいは使ってるとおもうわけだが。こいつがまたひどいバッドノウハウでさあ。ほとんどの人が他人の .screenrc をコピペしてきて済ませちゃうんだよね。俺くらいカスタマイズして使ってるやつとか見かけないわけよ。本当に。CodeRepos 見ても俺に比肩する規模の .screenrc 書いてる奴はいないもん。で、たまーにプロジェクタに表示して見せたりすると「それどうなってるんですか」とか。まあ一般人のおまえらは info なんか読まないよね。そうだよね。

でも今日は気が向いたから line-by-line で何が起こってるか解説しちゃうよ。

.screenrc の前にスクリーンショットの解説をちょっとだけ

[screenshot]これが普段俺が使ってるノート PC の画面である。これで全画面。OS は普通の Ubuntu で、端末は普通の gnome-terminal 。F11 でフルスクリーンにして、メニューバーも消してある状態。普段使いのフォントは M+ 2m 。いたって普通だ。普通でないところといえば gnome-panel が起動してないところか。そこは gconf-editor で弄った。gnome-panel ないとログアウトできない気がするかもしれないが、その問題は Widget Layer に必要なウィジェットを配置すると解決する。

で、gnome-terminal の中で何が起こっているかを解説すると、右半分に info screen が起動していて、左上は意味もなく banner(1) 。左下は tshark(1) で、よく読むと twitter のタイムラインを拾ってきていて、実はそれは画面の一番下に流れているんだけど、そのへんはあとで解説する。普段 screen を使ってる人ならおやと思うはずなのは

  • 縦分割
  • 分割線が謎の緑色
  • 異常に多い backtick
  • つか backtick に色がついている
  • しかも日本語が通っている
  • 左上の caption にだけ表示されている “GNU Screen of Git master” の謎の出力

くらいか。しかし実は謎の 33% は Git master というところで種明かしがされていて、つまり縦分割とか caption に日本語通すとかは git://git.savannah.gnu.org/screen.git からソース拾ってきて自力で make するだけで達成可能だったりする。

残りの部分は当然、バッドノウハウの結晶たる .screenrc の効果だ。

では早速 .screenrc を見てみよう

といっても .screenrc 自体は拍子抜けするほど短い。

source .screen/stem4
view raw .screenrc This Gist brought to you by GitHub.

一行である。仮にも *NIX の経験がある人間なら、即座に「これは .screen/stem4 という別のファイルを読み込んでいるのだな」というのは想像しなければならない

しかし自力で .screenrc を手書きしたことがある人にとっては、これだけでも十分な威力があるだろう。 source コマンドは .screenrc の諸機能のなかでももっとも不遇のコマンドで、これが使われているのを俺は見たことがない。本当はネットから拾ってきた .screenrc をおまえらの .screenrc にコピペする必要なんてなかったのに! 適当なディレクトリに wget(1) してきてただ source で読み込むだけでよかったのに!

というわけでここまで読んだおまえらは今日から source を使うように。なおネットから落としてきた設定をちょっとだけ変えたいおまえらのために、老婆心ながら同じコマンドが複数書かれていると後の方が有効という基礎的な事実を指摘しておく。

ちなみにこのコマンドでいったいどこのディレクトリにある .screen/stem4 を読み込んでいるのかはパラノイアには気になる所だが、これは info screen でちゃんと解説されていて、ファイル x にファイル y を読むコマンドがあると、

  1. x と同じディレクトリに y がないか探し、あればそれを採用する。
  2. なければ、screen(1) プロセスのカレントディレクトリに y がないか探し、あればそれを採用する
  3. それもなきゃエラー。

という順である。簡単ですね。なお後述の通りカレントディレクトリも .screenrc から弄れる。したがってここまでの依存関係をまとめると、

  1. まず screen(1) が起動して、~/.screenrc を読む。
  2. ~/.screenrc から source .screen/stem4 するので、~/.screen/stem4 をさがして、これはあるので、~/.screen/stem4 を読む。

となる。

stem4 と幹 screen たち

というわけで .screenrc は実態としては .screen/stem4 なるファイルと同一なのであった。このファイルを見てみよう。

source defaults
 
caption always "%{= dd}%`"
backtick 0 0 0 sudo ruby logmonitor.rb
 
screen screen -qUmc stem3
view raw stem4 This Gist brought to you by GitHub.

またしても短い。短いが、さっきよりはいろいろなコマンドが出てきている。一行ずつ見ていこう。

source defaults

まずしょっぱなで defaults というファイルを読み込んでいる。このファイルはあとからまだげっぷが出るほどエンカウントするので覚悟するように。内容はあとからまとめて解説しよう。 .screenrc がいくつものファイルに分かれているときなどには、このように source を活用すると本質的な記述に集中できる。ただでさええんがちょな .screenrc を少しでもきれいにするのにぜひ活用したい。

caption always "%{= dd}%`"

これは caption の設定だ。caption というのは screen の画面の下の方に hardstatus と一緒によく表示されているやつで、多くのおまえらには caption と hardstatus の違いがよくわからない。親切な俺がここで解説しておくと、

  • hardstatus はそもそも screen とか関係ない TTY の機能である。screen の場合はたまたまそれを「最下行に表示」という形で実装しているだけ。他の端末にはそれぞれの実装がある(実装してないこともある)。
  • 一方 caption は screen 固有の機能で、これは本来は画面を分割表示にしたときにどっちに何が表示されているかを示すためのもの。
  • ただし hardstatus alwayslastline と caption alsways は結果的に「下の方になんか表示するスペース」として使われるパターンが多い。
  • hardstatus は terminfo(5) を適切に設定すると screen の「外」の端末、たとえば xterm(1) とかからも見えるので、たとえば xterm のウインドウタイトルに表示したりすることができる。しかし caption は screen に閉じた世界なので、外部からは観測できない。
  • caption は split したときの振る舞いからあきらかなように per window で振る舞いを変更できるが、 hardstatus は全体で一個しかない。

おおむねこのような違いがある。stem4 の世界では画面分割はやらない(できない)ので、ここでの caption はずばり「下の方になんか表示するスペース」の用途である。

”%{= dd}%`” の部分は caption に表示するものを指定している。これは

"         " -- (1)
%{ } -- (2)
= dd -- (3)
%` -- (4)

このように区切って読む。(1) はただの区切り。(2) は色とかの指定ということを示していて、それは (3) に詳述されており、意味はその時点の設定を全部クリア (“=”) 、下線太字など装飾一切なし (” “) 、背景色デフォルト (“d”) 、前景色デフォルト (“d”) である。ようするに %{= dd} で「ふつうの表示にせよ」の意味。(4) は次の行で設定する backtick を表示せよという指示である。

ようするに人間が理解できるレベルの説明をすると「これから次の行のプログラムを表示するけど、余計なもん付けんといてね」という指定なのであった。これはひどい

backtick 0 0 0 sudo ruby logmonitor.rb

これが実際に起動するプログラムの指定である。0 0 0 は例によって「余計なことすんな」の意味で、起動するプログラムは sudo ruby logmonitor.rb だ。 sudo は syslog を読むために必要なのでつけている。セキュリティリスクとかはもちろん俺の自腹。

logmonitor.rb の内容は ruby の解説もしなきゃいけないので、あとで解説することにしよう。

screen screen -qUmc stem3

さて問題はこの行である。これはどういう意味か?

screen コマンドの screen [opts …] [cmd [args …]] は、screen のウインドウを新たに作成して、その中で cmd を実行する。つまり、screen screen とは、screen のウインドウの中で screen を起動する(!)

しかしそのままではうまくいかなかくて、普通に screen の中でシェルから screen を起動してみれば分かるように、普通は入れ子の screen は起動できないようになっている(親 screen で新たなウインドウが開く)。それを阻止するのが -m だ。これを指定することで screen は入れ子になれる。そして -c は設定ファイルを指定して、デフォルトの .screenrc を読まずに代わりに stem3 を読むことを意味している。

つまり stem4 の世界は、起動するとこうなる。

+---------------+
| +-----------+ |
| | stem3 | |
| +-----------+ |
| stem4 |
+---------------+

さあ、stem4 とか stem3 とかでおまえらも薄々気づいていたと思うが、そういうことである。以下にstem3を示す。

source defaults
 
caption always "%{= dd}%0`%=Battery %1`"
backtick 0 0 0 ruby cpumonitor.rb
backtick 1 9 9 ruby batmonitor.rb
 
screen screen -qUmc stem2
view raw stem3 This Gist brought to you by GitHub.

もちろんこれで

+-------------------+
| +---------------+ |
| | +-----------+ | |
| | | stem2 | | |
| | +-----------+ | |
| | stem3 | |
| +---------------+ |
| stem4 |
+-------------------+

こうなって、stem2 は言うまでもなく

source defaults
 
caption always "%{= dd}net %0`%=%1`%{= dd}"
backtick 0 0 0 ruby netmonitor.rb
backtick 1 0 0 sudo ruby hddmonitor.rb
 
screen screen -qUmc stem1
view raw stem2 This Gist brought to you by GitHub.
+-----------------------+
| +-------------------+ |
| | +---------------+ | |
| | | +-----------+ | | |
| | | | stem1 | | | |
| | | +-----------+ | | |
| | | stem2 | | |
| | +---------------+ | |
| | stem3 | |
| +-------------------+ |
| stem4 |
+-----------------------+

そろそろ飽きてきたと思うが stem1 がラストで

source defaults
 
caption always "%{= dd}%h%-023= %Y/%m/%d %02C:%s %A"
 
screen screen -qUmc leaf
view raw stem1 This Gist brought to you by GitHub.
+---------------------------+
| +-----------------------+ |
| | +-------------------+ | |
| | | +---------------+ | | |
| | | | +-----------+ | | | |
| | | | | leaf | | | | |
| | | | +-----------+ | | | |
| | | | stem1 | | | |
| | | +---------------+ | | |
| | | stem2 | | |
| | +-------------------+ | |
| | stem3 | |
| +-----------------------+ |
| stem4 |
+---------------------------+

これが俺の screen の一見して一番の特徴である「異常に多い backtick 」のしかけである。嗤えばいいと思うよ。しかし仕組みさえ分かってしまえば、この調子でどんどん backtick を増やしていけるのは容易に想像できると思う。俺の場合、以前はもっといろんな情報 (vmstat(1) とか)を表示したり、あるいはスタートレックもどき(反転表示が左右に移動する)みたいなただのデコレーションを入れて遊んだりしていたが、飽きたのと、さすがに端末の表示領域が削られすぎて本末転倒になってきたこともあって、厳選して今の数まで減らしてきたという感じである。

実際にいわゆる普通のシェルの類が起動しているのは、したがって leaf の中である。

いよいよもっとも普通の設定ぽい部分に突入だ

一見して分かる通り leaf はこれまでの stemN とは様相を大きく異にする。

source defaults
 
# Tell applications who this is. The ``screen-256color'' terminfo is in the
# ncurses-term package for debian.
term screen-256color
 
# Keys
escape ^Tt
zombie ^[
bind w windowlist -b
bind ^] paste [.]
bind u eval "encoding UTF-8"
bind e eval "encoding eucJP"
bind s eval "encoding SJIS"
bind j eval "encoding jis"
setenv LANG ja_JP.UTF-8
 
# default shell to invoke with ^T-c
shell /bin/zsh
 
# The scroll buffer
defscrollback 8195
markkeys h=^B:l=^F:$=^E:^U=^Z:^D=^V
 
# Messages
msgwait 3
msgminwait 2
 
hardstatus string "%?%h%:%t (screen #%n on %H)%?"
caption always "%{=r dd}%-Lw%40L>%?%F%{=b dR}%:[%? %n%f %t %?%F%{-}%:]%?%+Lw %?%F%-024=GNU Screen of Git master%:%=%?"
sorendition "+rb .G"
 
# default screens
chdir
screen -t zsh 0 zsh -l
view raw leaf This Gist brought to you by GitHub.

まず最初の

source defaults

に関してはもう特に言うことはないだろう。次に書いてあるのは、

# Tell applications  who this is.   The ``screen-256color'' terminfo is  in the
# ncurses-term package for debian.
term screen-256color

これはscreen の中から起動するプロセスに申告する環境変数の $TERM を何にするかという設定である。もちろんこの設定にするには OS に screen-256color の terminfo がインストールされている必要がある。コメントに書いてある通り、Debian 系なら ncurses-term を入れておくとよい。

ちなみにちょっと脱線するけど、$TERM は ssh 越しに伝わる環境変数のうちの一つである。したがってもし ssh するなら、ssh 先のマシンでも解釈できる値にしておかないといけない。とはいえ最大公約数をとると dumb とかになっちゃうし、毎回 $TERM 書き換えるのも面倒である。そういうときこそ screen は威力を発揮して、screen の場合ウインドウごとに異なる $TERM を設定できる。-T オプションである。screen -T hoge ssh localhost -t echo ’$TERM’ などとして実験してみよう。

本題に戻って、

# Keys
escape ^Tt

これはモディファイヤキーの設定だ。俺の場合は Ctrl+T を使っているが慣れているから以上の意味はなく、というか冷静に考えるとあまりいいキーだとは思えない。ただ Ctrl+A よりはマシ、程度の話でしかないだろう。

zombie ^[

zombie コマンドに何か引数を指定しておくと、screen の中でプロセスが死んだときに、そのキーを押すまではウインドウが残る。これを設定しておかないとプロセスがせっかく吐いたエラーメッセージやバックトレースが残らず消えてしまうので危険だ。必ず設定したい。なお知ってるとおもうが ^[ ってのはエスケープのことだ。

bind w windowlist -b
bind ^] paste [.]
bind u eval "encoding UTF-8"
bind e eval "encoding eucJP"
bind s eval "encoding SJIS"
bind j eval "encoding jis"
setenv LANG ja_JP.UTF-8

このへんはキーアサインの変更だ。たとえば Ctrl+T - W とすると、bind w に引っかかって、windowlist -b が実行されるといった塩梅。あんまりへんなキーは設定してないと思う。標準のキーアサインにあまり不満がないからか。

ところでふと思ったがこの bind u eval ”encoding UTF-8” の eval はひょっとしていらないんじゃないか? 後で試してみよう…

あとついでに setenv してるけど、これは本当についでというか、他に適当な場所がなかった。

# default shell to invoke with ^T-c
shell /bin/zsh

これは screen がただ screen として起動された時に中で何を動かすかの設定。zsh なのは趣味。

# The scroll buffer
defscrollback 8195
markkeys h=^B:l=^F:$=^E:^U=^Z:^D=^V

このへんは copy mode の設定である。 defscrollback は copy mode でバックログに保存される行数だ。バイト数ではないので注意が必要である。あんまし設定しすぎるとアクティブページをたくさん消費してしまうので速度が有意に低下する。逆に少なすぎると肝心のところがあっさりバックログから流れてしまう。8195行はどちらかというと設定しすぎの部類に近い。本当に大量にキャプチャしないといけないときは本来はファイルにログをとるべきだ (info 参照)。

markkeys は copy mode でカーソルを移動するキーの設定。これはたしか info からパクってきたはずだ。内容は : 区切りで、キー=意味、の組である。この設定だととりあえずhjklとか押してみるとなんとなく意味が分かる感じになっているはず。

# Messages
msgwait 3
msgminwait 2

ここでいう message とは何か。中で起動しているアプリケーションではなく、screen 自身がなにかを出力することがあるのだ。たとえば一番わかりやすいのはベル(^G)で音が鳴るかわりに Bell on window なんとかとか出力されたり、あるいは設定によってはかわりに Wuff Wuff とか表示されたりする。その他にも例えば monitor が設定されている時とか折に触れて screen はなんか喋ることがあり、あるいは極めつけは screen の中からruby -e ’puts ”\c[^hoge\c[\”’とかやると screen にメッセージを出力させることもできるわけだが、まあそういう表示をどのくらい表示するかの設定が上記だ。これだと、最大 3 秒最小 2 秒の表示になる。

hardstatus string "%?%h%:%t (screen #%n on %H)%?"

さて、screen の黒魔術の深淵に近付いてきた。これは stem4 でも言及した hardstatus の表示の設定だが、これまでより複雑である。

"                             "        --  (1)
%? %: %? -- (2)
%h -- (3)
%t -- (A) -+
(screen # -- (B) |
%n -- (C) > (4)
on -- (D) |
%H -- (E) |
) -- (F) -+

こんな感じに分解できる。(1) と (B) (D) (F) は見たままの意味につき省略。(2) がポイントで、この (3) か (4) どっちかを表示するという意味である。どっちが表示されるかは決まっているが、その決め方がよく分からない感じというか、少なくとも info に書いてあるのは嘘、あるいは嘘でなかったとしたら実装の方がバグってるってことになるので、まあその、頑張ってください。とりあえず(これでもまだシンプルな方の)この場合では、(3) があれば (3) 、なければ (4) である。

なお (3) は screen の中の人が指定した hardstatus (あれば)、(A) は screen の中の人のプロセス名、(C) は screen のウインドウ番号、(E) は screen が動いているホスト名である。たとえば一番上にあるスクリーンショットをよく見ると、stem1の位置に “banner (screen #3 on SZ92PS)” と表示されているのだが、この書式で生成されたものである。banner(1) は hardstatus を出力しないからである。

caption always "%{=r dd}%-Lw%40L>%?%F%{=b dR}%:[%? %n%f %t %?%F%{-}%:]%?%+Lw %?%F%-024=GNU Screen of Git master%:%=%?"

うーん、これ解説するの面倒だなあ。

まあでもとりあえず長すぎるので、いくつかの部分にわけて考えよう。この書式は、大きく分けて、

  • %{=r dd}
  • %-Lw%40L>%?%F%{=b dR}%:[%? %n%f %t %?%F%{-}%:]%?%+Lw
  • %?%F%-024=GNU Screen of Git master%:%=%?

に分かれる。最初のやつは色の指定だ。設定をクリアして (“=”) 、反転表示にして (“r ”) 、背景色デフォルト (“d”) 、前景色デフォルト (“d”) である。まあこれはいい。

次のがポルナレフ並に意味が分からないとおもう。これは以下のように分解できる。

%-Lw                       %n%f %t              %+Lw  -- (1)
%40L> -- (2)
%?%F %: %? %?%F %: %? -- (3)
%{=b dR} %{-} -- (4)
[ ] -- (5)

いきなり (1) からしてすげえ複雑度だが、これはこれだけで一式セットであり、screen ウインドウの一覧を表している。なんでこんなになっているかというと、%n%f %tの部分が「現在見えているウインドウの番号 (%n) フラグ (%f) 名前 (%t) 」で、その前後にいろいろな装飾をはさむことができるようになっているのだ。この場合は前後とも %?…%? がはさまっているわけだな。

(2) は横方向スクロールの指定だ。というのはつまり、ウインドウ一覧は何十個もウインドウがあるとあっさり横幅が爆発するので一行で収まらなくなるわけだが、そのときに一覧のどこのへんを表示するか。まあ普通に考えて今見えているウインドウの名前がスクロールアウトするのは悲しいわけで、今見えているやつのあたりが見えるようにしましょうね、というのが (2) の指定である。もうちょっと言うと、この > の位置が左から 40% くらいの位置にくるように、という指定だ。

(3) (4) (5) はまたしても「 (4) か (5) 」のどっちかを出力するやつだ。が、%F の場合は俺の経験によると %F が条件節、(4) が then 節で (5) が else 節だ。多分。条件である %F はフォーカス、つまりカーソルが点滅している箇所がどこにあるかで真か偽かが変わる。フォーカスが自分のウインドウの中にあれば真である。その場合は (4) に突入し、設定をクリアして (“=”) 、太字にして (“b ”) 、背景色デフォルト (“d”) 、前景色明るい赤 (“R”) である。%{-}は直前の色指定をキャンセルするらしい。(5) に突入すると、 [ … ] という出力になる。

さて最後の部分、これは長さが長いだけでここまでの知識でおおむね読める。

%?%F                              %:  %? -- (1)
%-024= -- (2)
GNU Screen of Git master -- (3)
%= -- (4)

こう分解できるのはいいよね? (1) に関してはここまでの話と同じなのでまあ、どうということはなくて、問題は (2) と (4) だ。この %= には二つの意味がある。まず表示する位置を決める。たとえば -024 だと、 = の位置が「右端から 24 文字目」の意味だ。次にスクロールの壁になる。つまりウインドウ一覧が長くなってくると一行に収まらなくなるんだけど、そのときでもウインドウ一覧に “GNU Screen…” が押し出されるのを防ぐ。実際にはウインドウ一覧のほうに %> が指定されているので、> の制約を満たしつつ、入りきらないものに関してはこの %= の位置でぶった切られる、という振る舞いだ。

以上、この長いキャプションの意味分かっただろうか。

sorendition "+rb .G"

あー、caption の解説終わったら気が抜けちゃったな。

でもこの sorendition に関しては一言言っておきたい。これも不遇のコマンドである。あまり指定してる人を見かけない。しかし実は screen の見た目を大きく左右する。ここれまででこの機能にちょっと関連しているのは message まわりだ。そう、sorendition は screen が自発的になんか表示するときの表示のされかたを決めているのである。ただしここでいう「なんか表示」にはメッセージ以外も含まれる。たとえば split したときの区切り線なども立派に「なんか出力」に含まれる。最初のスクリーンショットで緑色の縦分割になっていたのはこの設定のせいなのだ。値の意味はそれまでの設定をクリアしない (“+”) 、反転表示かつ太字 (“rb ”) 、背景色はそれまでを継承する (“.”) 、前景色は明るい緑 (“G”) である。スクリーンショットの範囲では太字はあんまし意味なさそうに見えるが、それこそ message とかを出力する時には効いてくる。

# default screens
chdir
screen -t zsh 0 zsh -l

最後のへんは screen プロセスが最初に起動した瞬間の設定である。

まず chdir は特に言うことはない。ただデフォルトとしてホームディレクトリに移動するというのは妥当だとは思う。次は 0 番に zsh を起動している。これも趣味の領域かとおもう。前は起動した瞬間からemacsやらなにやらが激しく起動する設定にしていたこともあるが、なんか結局はシェル一個に落ち着いてしまった。

デフォルトの部分

では何回も「あとで」と言って延期し続けてきた defaults を読んでみよう。

# Keys
# \233 is "Meta-Ctrl-[", or "Meta-Esc".
escape \233\233
 
# no zombie ... upper screen termination should propagate to this one.
zombie
 
# To use mouse. XT capability is screen specific, not seen in the system
# termcap / terminfo.
termcapinfo * XT
 
# Z0/Z1 are also screen specific.
termcapinfo xterm*|kterm*|screen* Z0=\E[?3h:Z1=\E[?3l
 
# To use hardware status line
termcapinfo xterm*|kterm*|screen* hs:ts=\E]0;:fs=\007:ds=\E]0;\007
hardstatus on
 
# To use 256 colors. AB/AF are also screen specific.
termcapinfo xterm*|kterm*|screen* Co#256:pa#32767:AB=\E[48;5;%dm:AF=\E[38;5;%dm
defbce on
 
# To use resize-window
termcapinfo xterm*|kterm*|screen* is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l
 
# Protection from attacks
multiuser off
idle off
 
# No visible bell because a stem screen should not intercept a bell.
vbell off
 
# No autodetach because a detached stem screen is useless.
autodetach off
 
# No startup message because a stem screen should not be invoked manually
startup_message off
 
# No login, otherwise /var/run/utemp will be squashed.
deflogin off
 
# obuflimit and autonuke can be controlled via termcap, but we do not have a
# way to get those values...
 
# A stem screen's output is another scren, so it is way much faster than a
# normal terminal such as xterm. 2 pyhisical pages should suffice.
termcapinfo screen* OL=8196
termcapinfo xterm* OL=256
 
# Nuke and pave.
autonuke on
 
# Dsiable scroll buffer, should be implemented in upper screens.
defscrollback 0
 
# chdir is useful for invoking scripts there.
chdir /home/shyouhei/.screen
 
view raw defaults This Gist brought to you by GitHub.

基本的な話として、defaults は stem たちが読むものである。stem はようするに caption の中で backtick を表示するだけの存在でいてほしい。つまり土管みたいなものになるべきである。したがって、ここの設定というのはできるだけ screen のおせっかいな機能をオフにするような設定であることが多い。

# Keys
# \233 is "Meta-Ctrl-[", or "Meta-Esc".
escape \233\233

\233 というのは TTY ではほとんど絶対入力されてこないキーの一つである。なんでかというと、おおむねの場合で Altキーと Esc キーは同じコードを吐くからだ。ちなみに、ありえないコードを指定するとどうなるの? と思ってescape ^!^! として実験すると、この場合は ^aと同じと解釈されるらしい。なかなかうまく行かないものである。

# no zombie ... upper screen termination should propagate to this one.
zombie

stem のゾンビが残っても意味ないので、さっくり消えてもらう。

# To  use mouse.   XT capability  is screen  specific, not  seen in  the system
# termcap / terminfo.
termcapinfo * XT

# Z0/Z1 are also screen specific.
termcapinfo xterm*|kterm*|screen* Z0=\E[?3h:Z1=\E[?3l

# To use hardware status line
termcapinfo xterm*|kterm*|screen* hs:ts=\E]0;:fs=\007:ds=\E]0;\007
hardstatus on

# To use 256 colors. AB/AF are also screen specific.
termcapinfo xterm*|kterm*|screen* Co#256:pa#32767:AB=\E[48;5;%dm:AF=\E[38;5;%dm
defbce on

# To use resize-window
termcapinfo xterm*|kterm*|screen* is=\E[r\E[m\E[2J\E[H\E[?7h\E[?1;4;6l

このへんは伏魔殿だ。screen と terminfo という、バッドノウハウとバッドノウハウの二重奏曲。濃厚なハーモニーを楽しんでいただきたい。とはいっても純粋に外の端末のケーパビリティを弄ってるのは is くらいのもので、他は screen の固有なケーパビリティである。たとえば XT とかは .screenrc の中でしか有効でない screen 専用の指定である。

なおこの is ケーパビリティの設定はどっかからパクってきたものだが、どうもなんとなくいけてない指定な気がしている。しかし伏魔殿すぎで調べる気も起きない。

# Protection from attacks
multiuser off
idle off

# No visible bell because a stem screen should not intercept a bell.
vbell off

# No autodetach because a detached stem screen is useless.
autodetach off

# No startup message because a stem screen should not be invoked manually
startup_message off

# No login, otherwise /var/run/utemp will be squashed.
deflogin off

このへんはおせっかい機能の停止である。特に指摘しておくべきなのはautodetach offだろうか。autodetach は多くの場合で screen の最重要機能だと思われているが、この場合はおせっかいなのである。たとえば無理矢理 autodetach を有効にした上で、一回コネクションを無理矢理切断してみる。

$ screen -x
There are several suitable screens on:
4508.pts-3.SZ92PS (Attached)
4499.pts-1.SZ92PS (Attached)
4496.pts-0.SZ92PS (Attached)
4504.pts-2.SZ92PS (Attached)
4511.pts-4.SZ92PS (Attached)
Type "screen [-d] -r [pid.]tty.host" to resume one of them.

わ か る か !(笑)

いや、まあ、上の図ならプロセス番号も pts も単調増加だから、たぶん pts-0 が正解だとは思うが、そういう風にプロセス番号とか pts とかがアロケーションされる保証はどこにもないし、たいてい autodetach されちゃう環境だと、えてしてその辺はカオスになるのである。デタッチされたらあきらめよう。そもそも backtick のプロセスが残っていたからといって嬉しさは軽微である。次回また起動すればいいんだから。

# A stem  screen's output is  another scren,  so it is  way much faster  than a
# normal terminal such as xterm. 2 pyhisical pages should suffice.
termcapinfo screen* OL=8196
termcapinfo xterm* OL=256

OL も screen 固有のケーパビリティだ。screen が持つバッファサイズ(ここは行ではなくバイト数)を決めている。xterm* のほうの設定は stem4 が使い、screen* のほうの設定はそれ以外の stem が使う。一番外の端末は当然、文字列を表示する必要があるのでそれなりに重い (X ならフォントのレンダリングとかも走る)が、stem 同士はただの土管だからそんなもんはなくて、超高速である。したがって大きめのバッファをとっておく。

なぜ 8192 を 8196 と typo しているかは書いた俺自身もよく分からない。

# Nuke and pave.
autonuke on

autonuke は screen の clear コマンドが発行された時に、その時点で上記のバッファに残っている出力をどうするか (on だと clear 時に捨てる)の設定なんだけど、stem ではそもそも clear しないからあんまし意味なかった。

# Dsiable scroll buffer, should be implemented in upper screens.
defscrollback 0

これもおせっかいをやめさせる感じである。stem にバックログがあってもなにも嬉しくない。

# chdir is useful for invoking scripts there.
chdir /home/shyouhei/.screen

defaults の最後では、このファイルがあるディレクトリに移動している。これは backtick のためにとても重要だ。fork したプロセスのカレントディレクトリは最初ここになるからだ。端的に言うと Ruby の場合のライブラリ探索パスに影響する。

長くなってきたんで一回ここで終わっていいですかね

本当はこれで backtick の中の Ruby のネタに綺麗につながって、twitter の timeline を流したりする楽しい部分がこれから続くんだけどな。でももう疲れた。続きはまた今度ー。

しかし次回は確実に Ruby メインなので screen パートのまとめをしておくか。えーと、これはひどい。screen はバザール型開発が失敗した例なんじゃないかとおもう。デザインの欠如的意味で。screen は本気を出せばすごい子なのに、設定がよくわからんとか悲しい理由でほとんどの人が使いこなせてないのは残念でならない。たしかに info 読んでもよく分からん部分も多いが、それでも info を読んで見るだけでもだいぶ大きい。ぜひみなさんもこの記事を参考に screen を使いこなして欲しい。

けど言っとくけどこの記事では screen のもっとも熱めの部分である eval / exec / stuff あたりには全然言及してないんだぜ。screen の深淵はまだまだ深いのだ。

ページ 1 の 1