Home » スタッフBlog » expectコマンドについて

expectコマンドについて

category : スタッフBlog 2017.10.3 

技術部の山口です。

今年もあっという間に10月となりました。
個人的には一番過ごしやすい季節ですが、体調等に気を付けて過ごしたいと思います。

最近は業務の方で四六時中linuxサーバに触れていますが、
先日あまり使用したことがなかった対話形式のコマンドを自動化する「expect」コマンドを使用しましたので、今回簡単に使用方法をご紹介したいと思います。

expectコマンドを使うことで、ユーザのキー入力等が必要なコマンドをスクリプト化させることができます。
「expect」という単語の意味は「期待する、予想する」というらしいです。
ちなみに「expect」という単語を聞いて真っ先に思い浮かぶであろう、某映画の有名な呪文も同じ意味らしいです。(こちらはラテン語らしいですが)

基本的な使い方ですが、

———————————————————-
#1. expectコマンドの開始
expect -c ”

#2. タイムアウトの秒数指定
set timeout “{秒数}”

#3. コマンドの実行
spawn “{コマンド}”

#4. 3のコマンド実行時に標準出力
expect “{標準出力}”

#5. 返答するコマンド
send “{コマンド}”

———————————————————-

大体、上記の5つのステップで構成されます。
スクリプトの最後に、ユーザの入力に戻りたい場合は、interact とすると戻ることができます。

実際の処理に当てはめて、SFTPをスクリプト化してやりたい場合は下記のようになります。

———————————————————-
#!/bin/bash

USER=$1
HOST=$2
PASS=$3
DIR=$4

expect -c ”
set timeout 30
spawn sftp ${USER}@${HOST}:${DIR}
expect
\”(yes/no)?\” {
send yes\n
expect password:
send ${PASS}\n
}
\”password:\” {
send ${PASS}\n
}
interact

———————————————————-

sftpコマンドを実行して、ホスト認証で警告が出た場合は
「Are you sure you want to continue connecting (yes/no)?」に対して「yes」を返答後にパスワードを返答し、標準出力に「${USER}@${HOST}’s password:」に対しては、パスワードを返答します。

上記の内容で、sftp接続する仕掛けが出来上がりました。
後はshに仕込んで、スケジューラで実行してテストするだけなんですが、気を付けなければならない問題があります。

実はこのスクリプトだとexpect処理中で異常終了した場合も、基本的に終了値0で終わってしまいますので、エラーロジック追加する必要があります。

私も業務で使用した際に、終了値0で終わっていたため、エラー検知されず処理失敗のまま数日の過ごしておりましたので、特に気を付けた方がよろしいポイントかと思っております。

では終了値を意識してエラーハンドリングを追加したものが、下記になります。

———————————————————-
#!/bin/sh

USER=$1
HOST=$2
PASS=$3
DIR=$4

expect -c ”
set timeout 30

spawn sftp ${USER}@${HOST}:${DIR}
expect {
default { exit 9 }
\”Name or service not known\” { exit 1 }
\”(yes/no)?\” {
send yes\n
expect password:
send ${PASS}\n
}
\”password:\” {
send ${PASS}\n
}
}

expect {
default { exit 9 }
\”Permission denied, please try again.\” { exit 2 }
\”invalid command\” { exit 3 }
\”sftp>\” { interact }
}

———————————————————-

ある程度予想できる標準出力に対しては特定の終了値を、それ以外の異常系は一律終了値9で終了するようになっております。(特に必要ない場合は0,1だけでもいいかと思いますが。)
これで何かしら異常終了した場合も、終了値0以外が返ってきます。

SFTPの場合はそもそも鍵交換でやれば、expect必要ないんじゃない?と思うかもしれませんが、接続先のサーバの都合で鍵交換できない場合もあるかと思います。
また私の場合は、開発で使用しているソフトウェアのコマンドラインツールが対話形式でしかできなかったので、使用することを余儀なくされました。
サーバ事情やソフトウェアの関係で、今後も使うことがありそうなコマンドなので覚えておきたいと思います。

タグ

サイト内検索

Copyright(c) 2017 IT-TERA All Rights Reserved.