Zsh
tmux

ssh中のtmuxのウィンドウ名をいい感じにする

More than 1 year has passed since last update.

たくさんのサーバで作業をしているとき,tmuxのウィンドウ名がsshだらけになることがあります.

20170730173747.png

しかし,このときに重要なのは各ウィンドウがどのサーバに接続されているかという情報です.
そこで,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
}

20170730174126.png

めでたく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