Help us understand the problem. What is going on with this article?

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

More than 3 years have 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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away