以前、GNU screenでレイアウトの整理
を作ってた時に、screen内の情報(どのlayoutが存在してるか、等)
情報を拾ってこれたらな、と思ってました。
screen -Q
コマンドとかにはかなり制限があって直接上手く取れませんでしたが、
screen -Q lastmsg
を使うことで簡単にとれたので、その方法について、
と使ってみての問題点について。
screen -Q
screen -Q
に引き続いてscreenコマンドを打つと、
その返り値をシェル側に返してくれます。
ただ、すべてのコマンドが使えるわけではなくて、次のコマンドのみ。
echo
info
lastmsg
number
select
time
title
windows
このうち、windows
なんかは、実際にscreen内で使ってステータスラインに表示される
ものとは若干違います
1。
screen -Q windows
などを上手く使えば何番のwindowが現在存在するのか、
等は分かりますが、layoutに関しては情報が直接取れません。
screen -Q lastmsg
そこで、lastmsg
を使います。
lastmsg
は最後にステータスラインに表示されたものを再表示するものですが、
これをscreen -Q
からやることで
screen内でステータスラインに表示できるすべての情報を取ってくることが出来ます。
screen内には、コマンドラインからでも
screen -X
を使ってコマンドを送ることができるので
(-X
の場合は直接コマンドを送るだけなのでコマンドに制限なし)、
$ screen -X layout show
$ screen -Q lastmsg
0 only 1* 4-windows 2 4-windows_2 3 3-win_1-top 4 3-win_1-left 5 monitor(-_-) $
こんな感じでlayoutの情報を取ってくることが出来ます。
さらに、screen内のコマンドの中でもこれは有効です。
screen内ではsetenv
コマンドで変数を使う事は出来るのですが、
シェルみたいにコマンド結果を収納したりは出来ないので
例えばlayout show
の結果に続いて何か表示させたいとかは出来ません。
これを、一旦外のシェルコマンドを通すことで可能に出来ます。
bind a eval 'exec /bin/sh -c "screen -X echo \"$(screen -X layout show && screen -Q lastmsg), n: next, p: prev, i: init\""'
$()
内のscreen -X
でステータスラインに情報を表示させてをれをscreen -Q lastmsg
で返し、
さらにそれをscreen -X echo
コマンドに渡すことでscreenのステータスラインに
最終的な表示をさせます。
それをexec /bin/sh -c "..."
を使ってキーバインドに渡します。
追記: 2014/05/25
eval
が抜けてたので加えてexec...
周りを'
で囲ってます。
追記ここまで
こんな感じでキーバインドを.screenrc
でしてあげれば、
screen内の情報を含めた複雑なメッセージもステータスラインに表示することが可能です。
問題点
と、結構良い感じで使える様になるな、と思ってたんですが、 色々アップデートして試してたら結構な率でクラッシュする様になってしまいました。
現象としては、
-
連続して短い間隔で
screen -Q
を含むキーバインドを使うとFilter running: … /bin/bash ….
みたいなメッセージがステータスラインに表示され、どうやら新しいコマンドが実行されなくなる。 (このコマンドがスタックしている。
この時、
/tmp/uscreens/S-USER/xxxxx.ttys002.yyy: connect: Connection refused
みたいにターミナルの情報に繋げられない、という様なメッセージがコマンドライン側に出ることも。
-
また、
screen -Q
を含むキーバインドを使った後、その時いたウィンドウで コマンドを打ってEnterを押しても実行されない(次の行に行くだけ)みたいになることも。 他のウィンドウからscreen -ls
してみると$ screen -ls There are screens on: xxxxx.ttys002.yyy (Attached) xxxxx.ttys002.yyy-queryA (Detached) 2 Sockets in /tmp/uscreens/S-USER.
みたいな感じで
queryA
というセッションができていて(xxxxxの番号はその上のものと一緒)Detached
になっている。この時、Enterを押しても実行されない。 ウィンドウからCmd-cを送ると ウィンドウ内は動くようになりますが、上の
Detached
だったものがDead???
状態になる。。 この時に、ps -u$USER|grep screen
とかで見てみると、screen -Q
関連の コマンドが残ってたりする。 なので、単にscreen -wipe
しただけではダメで変なプロセスが残っていって しまう可能性もある。
man screen
を見てみると
-Q Some commands now can be queried from a remote session using this
flag, e.g. "screen -Q windows". The commands will send the
response to the stdout of the querying process. If there was an
error in the command, then the querying process will exit with a
non-zero status.
となっていて、どうも中でquerying process
を新たなセッション(元の子セッション?)として立ち上げる、
みたいなことをしてるみたいです。
これが結構負荷が大きいようで繰り返し行うと詰まってしまう様です。
さらに、これがWindowsのCygwin上だと
コマンドラインからでもscreen -Q
を押した瞬間に固まり、
そのディレクトリにbash.exe.stackdump
というファイルが出来てたりすることがありました。
キーバインドに入れておいた場合も、一回目でも
Filter running: … /bin/bash ….
の表示が出て、
その時にbash.exe.stackdump
が出来ます。
multi_clipboard
を使ってる時もCygwinでこれが出てくることがあって、なんだろ、と思ってたんですが、
どうも中でscreen -Q
を使ってたのが悪かった様です
2。
Windows Vista/7で、最新のscreenやapt-cyg
で取ってこれるCygwin用にビルドされたもの等試してみましたが、
試した限りではすべての環境でscreen -Q
一発目でbsh.exe.stackdump
が出来て落ちました。
なのでCygwinではscreen -Q
は全く使い物にならないです。
(どれも結構古いマシンなので、Cygwinでもスペックの高いPCで使えば使えるのかもしれませんが。。。)
いずれにしろ、手元のMacやLinuxでも、結構なスペックの中でも
連続して使うと
Filter running: … /bin/bash ….
は出てスタックしてしまうのであまり使い勝手の良いものではありません。
ので、ここまで来てなんですが、
結論としてはscreen -X <cmd> & screen -Q lastmsg
の方法は(といよりscreen -Q
自体)
使わない方が良さそうです。
-
screen内では
This is window 0 (xxx).
みたいな感じで、コマンドラインから
screen -Q number
とすると、0 (xxx)
みたいに名前とcaptionだけが出ます。 (この表示はステータスラインにも表示される。) ↩
-
Cygwin以外でも余りよろしく無い様なので、multi_clipboard に関しては
screen -Q
でscreen内に変数を保持しておくのをやめました。 (外部ファイルに書いて読む、みたいなことをしてちょっと不格好ですが、 こちらの方なら安定して動くので。)