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
 "