expectコマンドの使い方

対話型のコマンドを自動実行したい場合に便利なexpectコマンドについてまとめてみます。あるコマンドを実行後、その応答を待って次のコマンドを実行する場合に、使用することで、定型処理の自動化が可能となります。

スポンサーリンク

インストール

デフォルトではインストールされていないことが多いので、インストールが必要です。Debian系のOSだと「expect」という名前のパッケージがあるのでインストールしておきます。

自動実行するコマンドの例

sshコマンドを実行する場合です。

userA@debian:~$ssh www.hoge.co.jp
Enter passphrase for key '/home/userA/.ssh/id_rsa':
Last login: Mon May 26 17:59:14 2008 from localhost
userB@kuroboxfo:~$ls -l
合計 1600
drwxr-xr-x   2 userB userB    4096 2008-03-24 17:55 TEMP
-rw-r--r--   1 userB userB     681 2008-03-21 17:01 apache.der
-rw-r--r--   1 userB userB     679 2008-03-21 16:48 Test.txt
drwxr-xr-x   2 userB userB    4096 2004-05-02 13:25 lost+found

ポイントは、sshのログイン時に秘密鍵を使ってログインするのですが、その秘密鍵のパスフレーズを入力するところと、ログイン後、コマンド「ls -l」を実行するところです。対話形式で入力が必要なコマンドの実行を自動化する場合に有効です。

スクリプトの実例

上記の自動実行したいコマンドをスクリプトにした例が下記になります。

#!/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

スクリプトの解説

上記スクリプトでの内容を解説します。一番の注意点は、1行目が「#!/user/bin/sh」でないことです。sh用のスクリプトではなくexcept用のスクリプトになります。スクリプトにはTclのコマンドを使用することができる。

コマンド 内容
set timeout 設定した秒数の間、標準入力から応答がないとexpectは、終了します。上記例だと、5秒でタイムアウトする設定になります。「-1」を設定すると、タイムアウトしない設定になります。
spawn 自動で実行したいコマンドを指定します。上記の場合、「ssh www.hoge.co.jp」を実行します。
expect 指定された文字列(「”」に囲まれた文字)と標準入力のデータとを正規表現で比較し、一致するまで以降の命令を実行しません。例だと、「Enter passphrase for key」が、画面に表示されるのを待つことになります。
send 指定された文字列(「”」に囲まれた文字)を先に実行したコマンドのジョブに送信します。つまり、「hogehoge38\n」とパスフレーズを入力したことになります。文字列最後の「\n」は、改行(Enterを押下)を意味します。
interact 実行ジョブの標準入出力をキーボードと画面に戻します。これで、自動実行を終了し、端末からsshでログインしたのと同じ状態になります。

スクリプト実行結果

実行結果は、次のようになります。sshでログインした後、「ls -l」を実行し、制御を端末に戻しています。

userA@debian:~$ ./ssh_conect.sh
spawn ssh www.hoge.co.jp
Enter passphrase for key '/home/userA/.ssh/id_rsa':
Last login: Mon May 26 18:51:27 2008 from localhost
userB@kurobox:~$ ls -l
totle 1600
drwxr-xr-x   2 userB userB    4096 2008-03-24 17:55 TEMP
-rw-r--r--   1 userB userB     681 2008-03-21 17:01 apache.der
-rw-r--r--   1 userB userB     679 2008-03-21 16:48 Test.txt
drwxr-xr-x   2 userB userB    4096 2004-05-02 13:25 lost+found
userB@kuroboxfo:~$

expectをシェルスクリプトで使用する方法

先のスクリプトでは、expect用のスクリプトでTclコマンドのみを使う事を前提としたスクリプトでしたが、他のコマンドと併用したい場合には、記述方法を変える必要があります。例えば、開始ログを出力したあと、自動ログインする場合、次のように記述します。

#!/bin/bash

echo "接続を開始します。" >> /tmp/ssh_connect.log

expect -c "
set timeout 5
spawn telnet localhost 25
expect \"220 kurobox\"
send \"ehlo localhost\n\"
expect \"250 HELP\"
send \"starttls\n\"
expect \"220 TLS go ahead\"
send \"quit\n\"
"

echo "接続を終了します。" >> /tmp/ssh_connect.log

開始ログを出力した後、telnetでメールサーバにアクセスします。次にTLS接続を開始後、接続を終了し、ログを出力します。ポイントは、命令の実行部分を「”」で囲む事、「”」内で使う「”」には、「\」エスケープ文字をつける事です。ちなみに、「expect -c」は通常のシェルスクリプト内のコマンドでその下の「expect」はTclのコマンドになります。

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク