たくさんのサーバで作業をしているとき,tmuxのウィンドウ名がsshだらけになることがあります.
しかし,このときに重要なのは各ウィンドウがどのサーバに接続されているかという情報です.
そこで,zshrc上にssh関数を作成し,sshが実行されたらホスト名をウィンドウ名にrenameするようにします.
調べてみるとこのような先行例[1]があります.
ssh() {
if [ "$(ps -p $(ps -p $$ -o ppid=) -o comm=)" = "tmux" ]; then
tmux rename-window "$(echo $* | cut -d . -f 1)"
command ssh "$@"
tmux set-window-option automatic-rename "on" 1>/dev/null
else
command ssh "$@"
fi
}
これでも十分実用に足るものですが,1つ問題があります.
sshを実行する際に何かオプションを指定したとします.
ssh -N hostname
このとき先ほどのssh関数のtmux rename-window "$(echo $* | cut -d . -f 1)"
の行に注目しましょう.
$*
でsshコマンドの引数をすべて渡してしまっているので,コマンドインジェクションのようなことが起きてしまいます.
結果として,tux rename-windowは以下のようなエラーを返します.
rename-window: illegal option -- N
usage: rename-window [-t target-window] new-name
今回の場合は関数の最後の引数をrename-windowに渡せば良さそうなので,先ほどのssh関数を以下のように修正します.
シェルスクリプトでは関数の引数をいくつかの方法で取得できます.
最後の引数は${@: -1}
によって取得します.
引数の取り扱いが正しいかよくわからないのですが,詳しく知りたい方は[2][3]あたりを詳しく読むとよいかもしれません.
修正したssh関数は以下のようになります.
ssh() {
if [ "$(ps -p $(ps -p $$ -o ppid=) -o comm=)" = "tmux" ]; then
tmux rename-window ${@: -1} # <---- ここ
command ssh "$@"
tmux set-window-option automatic-rename "on" 1>/dev/null
else
command ssh "$@"
fi
}
めでたくtmuxが見やすくなりました.
参考
[1] https://blog.no-panic.at/2015/04/21/set-tmux-pane-title-on-ssh-connections/
[2] http://qiita.com/zayarwinttun/items/0dae4cb66d8f4bd2a337
[3] https://fumiyas.github.io/2016/12/15/positional-parameters.sh-advent-calendar.html