GNU screen の裏にいる Window で完了したコマンドを Growl 通知したい
というようなことをつぶやいていたら、
Twitter / hchbaw: @typester 最近になって screen -Q windows とできるようになってますね。
と教えていただいた。
-Q
コマンドというのは -X
と同じようなものだけど、コマンド結果を screen 内のステータス領域ではなく標準出力で得ることができる。また、-X
はつねに実行時にそれ自体がアクティブな screen セッションになるのに対し -Q
はアクティブなセッションにクエリを投げる感じで、セッションが切り替わらない。(この辺は理解が怪しいので突っ込み歓迎)
それでそれを使うと
screen -Q windows
と実行することで :windows
で echo されるのとおなじ文字列を標準出力で得ることができる。その出力をパースすれば、自分が screen の裏にいるかどうか判断することができるというわけ。
zsh でコマンド完了時(正確にはプロンプトが表示される直前)に呼ばれるフックは precmd
なので以下のように定義:
function precmd() {
$HOME/bin/precmd.pl `history -n -1 | head -1`
}
シェルスクリプトかけないので Perl に逃げています。 で、precmd.pl は以下のような感じ:
#!/usr/bin/perl
use strict;
use warnings;
use FileHandle;
my $lastcmd = join ' ', @ARGV;
my $window = $ENV{WINDOW};
my $windows = qx{ screen -Q windows } or die "Your screen doesn't support -Q";
qx{ screen -X redisplay };
my $active;
for my $win (split "\x20\x20", $windows) {
my ($num, $flag, $title) = $win =~ /^(\d+)(.)? (.+)/;
if ($flag and $flag eq '*') {
$active = $num;
last;
}
}
if ($window != $active) {
open my $fh, "|/usr/local/bin/growlnotify -t 'GNU screen window $window'" or die $!;
print $fh sprintf 'command done: "%s"', $lastcmd;
print $fh "\n";
close $fh;
}
これで、コマンドが完了した場合にピコーンと通知が来るようになりました。
長い make や wget の時に超絶便利ですね!
書き忘れましたが、現在この機能をつかうためには開発版の screen を使用する必要があります。