2013年3月6日水曜日

ssh接続してコマンド実行するシェル

sshで接続先サーバでコマンド実行して、コマンドエラーをこちらのサーバ(接続元サーバ)で処理したかったときに作ったシェル。
もしかしたら、またどこかで使うかもしれないので記録しておく。
実際に作成したときはRHELだったが、以下はubuntu用で再現。
なので微妙にコマンドパスが違ったりする。
(RHEL : /bin/basename → ubuntu : /usr/bin/basename)

なお、運用管理系の自動実行用シェルだったので、公開鍵認証でssh接続する。
よって、そのための設定を予めしておく必要あり。
また、接続先でsudo実行する場合は、sudo設定(/etc/sudoers)も。
(以下のシェルではsudo実行してる。しない場合はsudoをとる。)

#/bin/sh
set -e

# このシェルの名前
CMDNAME=`/usr/bin/basename $0`

# 引数 $1   接続先(ユーザ名@ホスト)
# 引数 $2   接続先で実行するコマンド(シェル)
# 引数 $3~ コマンドオプション

# 引数2以下の場合はエラー
if [ $# -lt 2 ] ; then
  echo "usage: ${CMDNAME} [user@]hostname command [command option]"
  exit 255
fi

Dest=$1
Command=$2
Options=
if [ $# -gt 2 ] ; then
  for i in `seq 3 $#`
  do
    tmpval1=`eval echo \$\{$i\}`
    Options="${Options} ${tmpval1}"
  done
fi

# 実行結果を記述するログ
resultlog="/tmp/${CMDNAME}_${Dest}_${Command}.log"
# 秘密鍵(ここではuserの)
KYL="/home/user/.ssh/id_rsa"

# RET1:接続先での実行結果と戻り値
RET1=`ssh -n -T -i ${KYL} ${Dest} "sudo ${Command} ${Options}; echo return_code=\\$?"`
# RET2:ssh接続の戻り値(ssh通信の正常・異常を判定するために使う)
RET2=$?

# 接続先の実行結果の戻り値を抽出(制御文字を削除し、戻り値だけ抽出)
echo "${RET1}" > ${resultlog}
RET1=`/bin/grep return_code= ${resultlog} | /usr/bin/cut -d = -f2`
RET1=`echo ${RET1} | sed -e 's/[^0-9]//g'`

# 判定
if [ ${RET2} -ne 0 ]; then
  echo "${CMDNAME} : ssh connection failed (${Dest})"
  exit 1
elif [ "${RET1}" != "0" ]; then
  echo "${CMDNAME} : ssh command error at ${Dest} (command:${Command})"
  exit 2
fi
echo "${CMDNAME} : Succeed"
exit 0