Linuxコマンド
対話式コマンドでコマンドを自動実行させたい場合に使用するコマンドです。
インストール [#x62cc68c]
# yum install expect
使用方法 [#rf00b177]
#!/usr/bin/expect
set timeout 5
spawn ssh www.hoge.co.jp
expect "Enter passphrase for key"
send "hogehoge38\n"
expect "Last login"
send "ls -l\n"
interact
set timeout [#l0180c5d]
設定した秒数の間、標準入力から応答がないとexpectは、終了します。上記例だと、5秒 でタイムアウトする設定になります。
「-1」を設定すると、タイムアウトしない設定に なります。
spawn [#m33d7048]
自動で実行したいコマンドを指定します。上記の場合、「ssh www.hoge.co.jp」を実行します。
expect [#b25fdda8]
指定された文字列(「”」に囲まれた文字)と標準入力のデータとを正規表現で比較し、一致するまで以降の命令を実行しません。例だと、「Enter passphrase for key」が、画面に表示されるのを待つことになります。
send [#y7cea30a]
指定された文字列(「”」に囲まれた文字)を先に実行したコマンドのジョブに送信します。つまり、「hogehoge38\n」とパスフレーズを入力したことになります。文字列最後の「\n」は、改行(Enterを押下)を意味します。
interact [#sb0298c8]
実行ジョブの標準入出力をキーボードと画面にします。これで、自動実行を終了し、端末からsshでログインしたのと同じ状態になります。
log_file [#ub12bf93]
log_file ./expect_`date +%Y%m%d`.log
結果を指定したログへ出力できます。
実行結果は、次のようになります。sshでログインした後、「ls -l」を実行し、制御を端末に戻しています。
条件分岐 [#c8569836]
expectで条件分岐させるのは{}を使用することで可能です
下記スクリプトはSSH自動ログインして、rootまであがるスクリプトです。
{}の位置について、改行したりするとコマンドが実行されないので、下記文法の通りにすると良いです。
#!/bin/bash
export LANG=C
USER=user
PASS1=userpass
RPASS1=rootpass
HOST=$1
# expect コマンドを実行
expect -c "
# タイムアウト値の指定
set timeout 10
# spawnで新しいジョブ生成
spawn ssh ${USER}@$1
# login
expect \"Are you sure you want to continue connecting (yes/no)?\" {
send \"yes\n\"
expect \"$USER@$HOST's password:\"
send \"${PASS1}\n\"
} \"$USER@$HOST's password:\" {
send \"${PASS1}\n\"
}
# rootへ昇格
expect ${USER}
send \"su\n\"
expect Password:
send \"${RPASS1}\n\"
# logout
expect root
send \"exit\n\"
expect ${USER}
send \"exit\n\"
# spawnジョブを通常の通信にする
interact
"