GNU Screenでタブをまとめるタブ(入れ子型ウィンドウグループ)で大量のウィンドウを管理する

スポンサード リンク
LINEで送る
Pocket

はじめに

GNU screenで,タブをまとめるタブ的なUIでウィンドウグループを実現する方法を紹介する。正確には,ウィンドウをまとめるウィンドウだが。

Screenの入れ子によるウィンドウグループの実現

Screenの入れ子によるウィンドウグループの実現

(能書きはいいから,という人はとにかくお前の.screenrcを見せろをご覧ください)

みなさんは,GNU Screenで大量のウィンドウを開くときどうやって管理しているだろうか。正面から攻めるならウィンドウグループ(window group)を使うのが普通であり,すでにかなり詳しい説明がある(下URL参照)。

開発版GNU Screenで楽々ウィンドウ管理 – Keep It Simple, Stupid
これからの「GNU Screen」の話をしよう – Keep It Simple, Stupid

記事を初めて読んだときは,すごい!と思って僕もウィンドウグループを使って大量のウィンドウを捌こうとしてみた。が,ウィンドウの役割ごとに番号を決めて……という運用では定形作業なら良いけれども,適当な作業ばかりしている僕にはウィンドウと番号の関係を把握しきれないことが判明した。だからこそ,グループ化して管理したかったわけでありまして……。

まぁ,windowlistを見ろって話なんだが,そのためだけに領域を1つ消費するのは断じて許せない。しかも,「次のウィンドウに移る」,「前のウィンドウに移る」のと同じ感覚で「次のウィンドウグループに移る」,「前のウィンドウグループに移る」ショートカットキーが無いのは個人的には致命的と思う。

そこで,卜部昌平のあまりreblogしないtumblr – 俺の .screenrc が火を吹くぜにあるようなSTEM-LEAFの入れ子によって「入れ子型ウィンドウグループ」を実現することにした。

動作確認しているバージョンは Screen version 4.01.00devel (GNU) 2-May-06 および Screen version 4.02.01 (GNU) 28-Apr-14 である。

設定方法

グダグダ書いてしまったが,やり方は.screenrcを次のような感じで変更するだけ。STEMがウィンドウグループで,LEAFがグループのメンバーとなるウィンドウに対応する。(コピペするならとにかくお前の.screenrcを見せろ的なアレをご覧ください)

# STEMとLEAFの共通設定を読み込む
source .screenrc_defalut
# STEM側のPrefixキーの設定
escape ^Gg
# STEM側ではhardstatusだけ表示すれば十分。captionはいらない。
hardstatus on
hardstatus alwayslastline '%{= .m}%H%{-}%{= kw} %L=%-w%45L>%{= m.}%n %t%{-}%+w %-17<%=%m/%d %02c:%s'
sorendition '+r .m'
# STEM側で新しいウィンドウを開くときは忘れずにLEAFも起動するようにする
bind c eval 'screen screen -qmc .screenrc_leaf -S leaf' 'title \n'
# LEAFのscreenを起動
screen screen -qmc .screenrc_leaf -S leaf

で,.screenrc_leafでは,Prefixキーをダブらないように設定しておく。

# STEMとLEAFの共通設定を読み込む
source .screenrc_defalut
# LEAFでは普通にhardstatusとcaptionを設定する。でもホスト名の表示はSTEM側でやるので要らない。
hardstatus on
hardstatus alwayslastline '%{= .m}%H%{-}%{= kw} %L=%-w%45L>%{= m.}%n %t%{-}%+w %-17<%=%m/%d %02c:%s'
caption always '%?%F%{= mw}%:%{= wk}%?%2n%f%07=%t%='
sorendition '+r .m'
# LEAF側のPrefixキーの設定
escape ^Tt

これで入れ子にできるので,冒頭の画像のようになる。グループを操作したいときは ^G,ウィンドウを操作したいときは ^T をプレフィックスにするだけで後は全く同じだから使いやすい!

入れ子型ウィンドウグループの問題点

どれがSTEMだかわからなくなる問題

ちなみに,卜部昌平のあまりreblogしないtumblr - 俺の .screenrc が火を吹くぜで指摘されている問題,

特に指摘しておくべきなのは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.

わ か る か !(笑)

という,名づけて「どれがSTEMだかわからなくなる問題」は,それぞれの.screenrcでsessionnameを指定しておけば回避できる。例えば,STEMのsessionnameをSTEM,LEAFのsessionnameをLEAFにすれば,

$ screen -list
There are screens on:
        16847.STEM      (Attached)
        16210.LEAF      (Attached)
        16207.LEAF      (Attached)
3 Sockets in /home/hoge/.screens.

となる。だが,.screenrcにsessionnameを設定してはいけない

というのも.screenrcでsessionnameを指定しておくと,ターミナルのウィンドウサイズ変更にscreenが追従しなくなるからだ(下画像参照)。何かのバグなのだろうか(うちの環境だけ?)。なお,実用上は screen -r で自動的にSTEMにリタッチしてくれるのでsessionnameを設定する必要はほぼ無い。

sessionnameを指定すると,ウィンドウサイズの変更に追従しない

sessionnameを指定すると,ウィンドウサイズの変更に追従しない


なお,起動時の引数,つまり screen -S sessionname の形式で指定するとこの問題は発生しない。sessionnameを指定する際はこちらをオススメする。

ウィンドウグループの変更ができないよ問題

さっきのとは別に「ウィンドウグループの変更ができないよ問題」もある。

当たり前だがLEAFはグループごとに別プロセスであり,グループ1のウィンドウをグループ2に移動するといったことは基本的にできない。やったことは無いが,reptyr(参考:ptraceを駆使してscreenifyっぽいことをするreptyrがすごい)みないたことをすれば出来なく無くは無いのかもしれないが,そこまでやる必要性も(僕には)ない。

とにかくお前の.screenrcを見せろ的なアレ

今回の変更を加え,肥大化した僕の.screercを載せておく。ssh先screenのペーストバッファをクリップボードに貼り付ける - Keep It Simple, Stupidを導入しているなら,コピペでそのまま使えると思う。ダメだったらごめんなさい。

.screenrc

# STEMとLEAFの共通設定を読み込む
source .screenrc_default

# スクロールバッファは無効にする
defscrollback 0
# セッション名をつける
# つけると何故か画面リサイズで表示が崩れるので無効にしている
#sessionname stem
# Prefixキーの設定
escape ^Gg
#通常の操作キー
bind c eval 'screen screen -qmc .screenrc_leaf -S leaf' 'title \n'
# hardstatus and caption
hardstatus on
hardstatus alwayslastline '%{= .m}%H%{-}%{= kw} %L=%-w%45L>%{= m.}%n %t%{-}%+w %-17<%=%m/%d %02c:%s'
sorendition '+r .m'

# デフォルトレイアウトを作成
layout new 0:def
layout select 0
# 子screenを起動
screen screen -qmc .screenrc_leaf -S leaf
title \n

.screenrc_leaf

# STEMとLEAFの共通設定を読み込む
source .screenrc_default

# スクロールバッファ
defscrollback 100000
# Prefixキーの設定
escape ^Tt
# automatically set title
setenv SCREENTITLE auto
# hardstatus and caption
hardstatus on
hardstatus alwayslastline '%L=%-w%45L>%{= m.}%n %t%{-}%+w %-1<%='
caption always '%?%F%{= mw}%:%{= wk}%?%2n%f%07=%t%='
sorendition '+r .m'

#ウィンドウを作成
screen 0
screen 1
# デフォルトレイアウトを作成
layout new 0:def
layout select 0
split -v
select 0
focus next
select 1
focus prev

.screenrc_default

# 現在の背景色で消去する
defbce "on"
# 太字には明るい色を使う
attrcolor b "
56色表示設定
term xterm-256color
termcap OP
# 新しいウィンドウを生成するときのコマンド
shell $SHELL
# 別画面サポート。Vimやless使うときに便利
altscreen on
# ビジュアルベル(画面全体が点滅する)を切る
vbell off
# ベルの時はメッセージ(+音)を出す
#bell_msg "Bell in window %"
# 端末が落ちたら自動的にデタッチする
autodetach on
# スタートアップメッセージを消す
startup_message off
# ログファイルのファイル名
logfile "$HOME/.screens/screen-%Y%m%d-%n.log"
# 標準でログをとる
#deflog on
# ウィンドウのタイトル指定
## 後半の 'zsh' は指定のない時に表示される
shelltitle '$ |zsh'
#メッセージを表示する時間(秒単位)
msgwait 5
#次のメッセージを表示するまでの遅延時間(秒単位)
msgminwait 1
# ペーストバッファを保存するファイル
bufferfile $HOME/.screen_exchange

#ウィンドウ操作モード
bind w eval 'echo "Operate window"' 'command -c operate'
bind -c operate ^]  command
bind -c operate j eval 'focus down' 'command -c operate'
bind -c operate k eval 'focus up' 'command -c operate'
bind -c operate h eval 'focus left' 'command -c operate'
bind -c operate l eval 'focus right' 'command -c operate'
bind -c operate t eval 'focus top' 'command -c operate'
bind -c operate b eval 'focus bottom' 'command -c operate'
bind -c operate K eval 'resize -v +1' 'command -c operate'
bind -c operate J eval 'resize -v -1' 'command -c operate'
bind -c operate L eval 'resize -h +1' 'command -c operate'
bind -c operate H eval 'resize -h -1' 'command -c operate'
bind -c operate = eval 'resize -v =' 'command -c operate'
bind -c operate + eval 'resize -h =' 'command -c operate'
bind -c operate s eval 'split' 'command -c operate'
bind -c operate c eval 'screen' 'command -c operate'
bind -c operate x eval 'remove' 'command -c operate'
bind -c operate v eval 'split -v' 'command -c operate'
bind -c operate 0 eval 'select 0' 'command -c operate'
bind -c operate 1 eval 'select 1' 'command -c operate'
bind -c operate 2 eval 'select 2' 'command -c operate'
bind -c operate 3 eval 'select 3' 'command -c operate'
bind -c operate 4 eval 'select 4' 'command -c operate'
bind -c operate 5 eval 'select 5' 'command -c operate'
bind -c operate 6 eval 'select 6' 'command -c operate'
bind -c operate 7 eval 'select 7' 'command -c operate'
bind -c operate 8 eval 'select 8' 'command -c operate'
bind -c operate 9 eval 'select 9' 'command -c operate'

#通常の操作キー
bind x remove
bind j eval 'focus down'
bind k eval 'focus up'
bind h eval 'focus left'
bind l eval 'focus right'
bind K eval 'resize -v +1'
bind J eval 'resize -v -1'
bind H eval 'resize -h +1'
bind L eval 'resize -h -1'
bind v eval 'split -v' focus screen
bind s eval 'split' focus screen
bind = eval 'resize -v ='
bind + eval 'resize -h ='
bind a eval 'title'
bind ^h eval 'focus left'

# レイアウト関連操作
# 開発版GNU Screenのlayoutを使ってみよう - Keep It Simple, Stupid
# http://yskwkzhr.blogspot.jp/2011/12/guide-to-using-gnu-screen-layouts.html
# trigger for layout sub-commands
bind ^Y eval 'command -c layout' 'layout show'
bind y  eval 'command -c layout' 'layout show'
# create/remove layout
bind -c layout c eval 'layout new'    'layout show'
bind -c layout X eval 'layout remove' 'layout show'
# change the current layout title or number
bind -c layout A colon 'layout title '
bind -c layout N colon 'layout number '
# switch to the layout identified by number or title (not prefix of a title)
bind -c layout \' eval 'layout select' 'layout show'
# switch to other layout
bind -c layout n eval 'layout next'     'layout show'
bind -c layout p eval 'layout prev'     'layout show'
bind -c layout 0 eval 'layout select 0' 'layout show'
bind -c layout 1 eval 'layout select 1' 'layout show'
bind -c layout 2 eval 'layout select 2' 'layout show'
bind -c layout 3 eval 'layout select 3' 'layout show'
bind -c layout 4 eval 'layout select 4' 'layout show'
bind -c layout 5 eval 'layout select 5' 'layout show'
bind -c layout 6 eval 'layout select 6' 'layout show'
bind -c layout 7 eval 'layout select 7' 'layout show'
bind -c layout 8 eval 'layout select 8' 'layout show'
bind -c layout 9 eval 'layout select 9' 'layout show'
# continuous switch to other layout
bind -c layout ^N eval 'layout next' 'command -c layout' 'layout show'
bind -c layout ^P eval 'layout prev' 'command -c layout' 'layout show'

# ssh先screenのペーストバッファをクリップボードに貼り付ける - Keep It Simple, Stupid
# http://yskwkzhr.blogspot.jp/2011/04/copying-remote-screen-paste-buffer.html
# ペーストバッファをPRIMARYにコピー
bindkey -m ' ' eval 'stuff \040' writebuf 'exec  sh -c "cat $HOME/.exchange.key $HOME/.screen_exchange | nc -w1 localhost 52224"' 'echo "paste to remote"'
bindkey -m 'y' eval 'stuff y' writebuf 'exec     sh -c "cat $HOME/.exchange.key $HOME/.screen_exchange | nc -w1 localhost 52224"' 'echo "paste to remote"'
bindkey -m 'Y' eval 'stuff Y' writebuf 'exec     sh -c "cat $HOME/.exchange.key $HOME/.screen_exchange | nc -w1 localhost 52224"' 'echo "paste to remote"'

関連する記事

LINEで送る
Pocket



カテゴリー: CentOS, CUIでいこう, Cygwin, Debian, Fedora パーマリンク

コメントを残す

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
また,TeX の記法で数式を入力する場合は [latexpage] とコメントの最初に入力してください(QuickLaTeX の機能です)。
例: [latexpage] $\frac{1}{2}$

ERROR: si-captcha.php plugin: GD image support not detected in PHP!

Contact your web host and ask them to enable GD image support for PHP.

ERROR: si-captcha.php plugin: imagepng function not detected in PHP!

Contact your web host and ask them to enable imagepng for PHP.