はじめに
最近以下の記事を見てtmuxのペイン毎にステータスラインを表示できることを知りました。
リンク先の記事の通り、ssh先ホスト名やgitブランチなどを表示するのもいい感じなのですが
個人的に表示したかったのは「最後に実行したコマンド」です。
特にmake
など長時間かかってログが流れて行ってしまうようなコマンドで、後から「どのオプションを付けたっけ?」と思うことがたまにあります。
tmuxのhistoryにプロンプトが残っていればいいのですが、そうでなかった場合ps
かシェルの履歴で探すしかないですし、同じコマンドをオプション変えながら複数流していたらお手上げです。
というわけで「最後に実行したコマンド」を表示できるようにしてみました。
方法
最低限の設定としては以下を.tmux.conf
に追加すればOKです。
set -g pane-border-format "#(ps --no-headers -t #{pane_tty} -o args kstart_time | grep -v '^-.*' | head -n 1)"
実際には"tmuxのペインのステータスラインにgitのブランチとかディレクトリとか表示する(プロンプトはもう古い)"に書かれている通り、スクリプトを呼ぶ形にした方がいろいろ便利です。
あと、ステータスラインの更新間隔をある程度短くした方がいいかもしれません。
set -g status-interval 1
ステータスラインの更新はtmux refresh-client -S
コマンドを実行することでもできるので、
シェルのhookを使ってこのコマンドを呼ぶのが一般的です。
しかし、長時間のコマンドを実行してしまった場合、シェルに制御が返ってこないので呼べるhookがありません。
そのためtmuxが自力で更新するしかなく、status-interval
が長いとなかなか反映されないことになります。
解説
一応コマンドの解説です。
まず#{pane_tty}
がそのペインのttyになるので
ps --no-headers -t #{pane_tty} -o args kstart_time
でそのペインのプロセス一覧が得られます。
-o args
で引数付きのコマンド出力に、kstart_time
で起動順にソートされます。
ソートなしだと、例えばmake
が内部でgcc
を呼ぶような場合にどれが最初のコマンドか分かりません。
あとはソートされた先頭コマンドを表示すればいいのですが、
プロセス一覧にはログインシェルも含まれるので先頭は必ずログインシェルになってしまいます。
そのため以下でログインシェルを除いています。
grep -v '^-.*' | head -n 1
ps
によるプロセス一覧のうちログインシェルは行頭に-
がつくのでgrep
で除外できます。
あるいは以下のように単に1行目を除外でもいいかもしれません。
head -n 2 | tail -n 1
実際の設定
最後に、私が使っている設定全体へのリンクを張っておきます。
tmux-pane-border
スクリプトは"SSH接続先のホスト名をtmuxのペインに表示する(大事件)"のものを改変させていただきました。
ありがとうございます。