notebook

都内でWEB系エンジニアやってます。

tmuxで複数ペインに対してコマンドを送る

tmuxで複数ペインに対してコマンドを送る

最近担当サービスの本番サーバ台数が増えてきました。

リリースでの再起動だったり、調査ですべてのサーバの様子見に行ったりする事があったのですが毎回対象サーバにsshして.....っていう流れが面倒になってきました。

なので本番サーバに一括でコマンド送ったりできたら便利だなという事でちょっと調べてみた。

参考: tmux起動時にsshで自動でログインしログイン後にコマンドを実行する方法

これ使えば各ペインに同時にコマンド送れるじゃん!ってことで上記記事を参考にスクリプト書いてみました

#!/bin/bash

_usage() {
  echo "usage:"
  echo "${0} -g [back|front] -m [pane|pass|input]"
  exit 1
}

while getopts g:m: opt
do
  case ${opt} in
    "g")
      set_options='y'
      group=${OPTARG};;
    "m")
      set_options='y'
      mode=${OPTARG};;
    :|\?) _usage;;
  esac
done

[ "${set_options}" != 'y' ] && _usage

case $group in
  'back')
    servers=( 1 2 3 4 5 6 7 8 9 10 )
    name='back'
    ;;
  'front')
    servers=( 11 12 )
    name='front'
    ;;
  *)
    _usage;;
esac

case $mode in
  'pane')
  tmux new-window -n ${name}
  tmux split-window -v

  for (( i = 0; i < ${#servers[@]}; i++ ))
  do
    if [ $((  $i % 2  )) -eq 0 ]; then
      tmux split-window -v -t ${name}.$i
    else
      tmux split-window -h -t ${name}.$i
    fi

    tmux send-keys -t ${name}.$i "ssh user@*.*.*.${servers[$i]}" C-m
  done

  tmux select-layout tiled
  ;;

  'pass')
  echo "Input Password:"
  stty -echo
  read command
  stty echo
  for (( i = 0; i < ${#servers[@]}; i++ ))
  do
    tmux send-keys -t ${name}.$i "$command" C-m
  done
  ;;

  'input')
  echo "Input Command:"
  read command
  for (( i = 0; i < ${#servers[@]}; i++ ))
  do
    tmux send-keys -t ${name}.$i "$command" C-m
  done
  ;;

esac
  • 一括で管理したいサーバの数にあわせて複数ペインを開く
  • スクリプト側で対象サーバへログインするコマンドを叩く
  • -m input でコマンドを入力したコマンドが各サーバ(各ペイン)で実行される(ペインが複数ある事が前提)
  • パスワード入力時のために -m passを用意

やってる事はサーバの数だけsend-keysでコマンドを送ってるだけですね

tmux split-window -h tmux split-window -v を交互に行う事でペインの数がある程度増えても大丈夫なようになってます。

sttyでコンソールでの入力値の表示をコントロールできるようになってます。 -echoで非表示、echoで表示

とりあえず個人的に使うだけなら結構便利に使ってます。

ちょっといじって今の運用ルールに沿ったものも書いたので多少運用が楽になるかなー