expect内でループ処理をする。
Linux等のリモートサーバ上で自動的に処理をさせたい場合、expectを使うのが一般的です。
今回はexpectを使って、リモートサーバ側でwhileを使った処理をさせた時のメモです。
今回やりたかったことは、サーバAからサーバBにログインし、複数ノードにPingを打つ、というような処理です。
expectの構文はtcl文法
今までよく知らずに使っていましたが、expectはtcl文法を使っていたので、下記の書式でループを作ることができました。
while { 条件式 } { 処理 }
例) sshで入ったサーバから、192.168.1.0-128のノードにPingを打って抜ける。
こんな感じで出来ました。
#!/bin/bash SSHHOST=hoge001 password="hogehoge" PINGHOST="192.168.1." expect -c " spawn ssh -l root $SSHHOST expect \"password:\" { send \"$password\n\" } \"Are you sure you want to continue connecting (yes/no)?\" { send \"yes\n\" expect \"password:\" send \"$password\n\" } set i 0 while {\$i <= 128} { send \"sleep 1\n\" expect \"\[$username@$hostname ~\]$\" send \"/bin/ping -c $PINGHOST\$i\n\" expect \"\[$username@$hostname ~\]$\" incr i 1 } send \"sleep 1\n\" expect \"\[$username@$hostname ~\]$\" send \"exit\n\" interact "
ハマったところ
expect内で定義した変数(上記の例では"i")は、変数を使う時、事前にバックスラッシュ or 円記号を付けないとダメでした。
expect外で定義した変数は"$username"といった形で呼び出せます。
expect内で定義した変数は \$変数名 とする。
i => \$i
expect外で定義した変数は $変数名 でOK。
username => $username