expectコマンドでscpを自動化(cronで実行)する
scpで別サーバにファイルを転送する際に、別サーバ側の認証が入る。
これをシェルスクリプトで行う場合、expectというコマンドを利用します。
expectで利用される主なコマンドは以下となります。
expect -c:ダブルクォートで囲った複数行を自動対話処理する spawn:コマンドを実行する expect:対話の受信 send:対話の送信 interact:対話の終了 "\r":リターンコード
シェルスクリプトを以下の様に作成します。
対話処理が複数回発生する場合は、それごとにexpectを記述してください。
#!/bin/sh HOST=192.168.10.10 USER=ログインユーザ PASS=パスワード TARGET_FILE=/var/www/backup.tar.gz BACKUP_DIR=/backup/ /usr/bin/expect -c " set timeout 30 spawn /usr/bin/scp -p ${TARGET_FILE} ${USER}@${HOST}:${BACKUP_DIR} expect { \"password: \" { send \"${PASS}\r\" } } interact "
ここで手動でシェルスクリプトを実行すると、正常に別サーバに転送されるはずです。
しかし、これをcronにて自動的に実行すると、先程と同様な結果になりません。つまり転送が失敗します。
理由はcron自体がdaemonとして実行されているので「対話の終了」という認識がされないとか言われてます。
そこでシェルスクリプトを以下の様に書き直します。
#!/bin/sh HOST=192.168.10.10 USER=ログインユーザ PASS=パスワード TARGET_FILE=/var/www/backup.tar.gz BACKUP_DIR=/backup/ /usr/bin/expect -c " set timeout 30 spawn /usr/bin/scp -p ${TARGET_FILE} ${USER}@${HOST}:${BACKUP_DIR} expect { \"password: \" { send \"${PASS}\r\" } } expect { eof { exit 0} } "
interactの代わりにeofで受けます。
この際、正常終了なら「exit 0」、異常終了なら「exit 1」とか返り値を与えることが出来ます。
書き換えたシェルスクリプトはcronでも手動でも実行可能となります。
ディスカッション
コメント一覧
まだ、コメントがありません