expect コマンドを使用すると、任意のコマンドの出力を待ち受けて、自動でそれに応答するといったことを実現できます。
expect の基本的な使い方
Linux のコマンド expect
がインストールされていない場合は、パッケージ管理ツール(apt
や yum
)を使用してインストールしてください(macOS には最初からインストールされています)。
まずは、簡単な例として、下記のような簡単なユーザ入力を必要とするスクリプトを自動で動作させてみます。
これをそのまま実行すると、下記のようにユーザ入力の待ち受け状態となります。
$ ./greet.sh
Enter your name:
このような状態になったときに、自動的に入力を行うには、下記のように expect -c
コマンドを使ったシェルスクリプトを作成します。
expect -c
の後ろのダブルクォートで囲まれた部分には、expect
で実行するスクリプトを記述します。
この中でダブルクォートを使用したいときは、\"
のようにエスケープしなければいけないことに注意してください。
スクリプト中の各行は次のような意味を持っています。
set timeout 3
… 外部プログラムの実行を 3 秒待つspawn ./greet.sh
… 指定した外部プログラム (./greet.sh
) を実行するexpect "Enter your name:"
… 外部プログラムの出力 (Enter your name:
) を待つsend "Makun"
… 外部プログラムに Maku と入力して、最後に Enter を入力するinteract
… 外部プログラムとのインタラクションへ戻る
上記のシェルスクリプトを実行すると、外部プログラム greet.sh
の入力待ちに対して、自動的に Maku
という入力を行います。
コマンドラインからのパスワード入力を自動化する
あまりよくない例かもしれませんが、ssh
や rsync
コマンドなどのパスワード入力も同様に自動化することができます。
下記のスクリプトを実行すると、ssh
コマンドがパスワード入力を求めてきたときに、自動でパスワードを入力してログイン処理が完了します。
ログイン後に、何らかのコマンド(例えば ls -aFl
)を実行するところまで自動化したいのであれば、下記のようにプロンプトの $
を待ち受けて次の入力を行えばよいでしょう。
#!/bin/bash
expect -c "
set timeout 3
spawn ssh username@example.com
expect \"password:\"
send \"x5sd6sfc\n\"
expect \"$\"
send \"ls -aFl\n\"
interact
"
ちなみに、rsync
コマンドでファイル転送するときも同様にパスワード入力を自動化できます。
#!/bin/bash
expect -c "
spawn rsync -r -h -v --delete public user@example.com:public
expect \"Password:\"
send \"abcabcabc\n\"
interact
"
ただし、このような使い方をすると、シェルスクリプトにパスワードをそのまま記述することになるので、ファイルの保存場所には十分に注意してください。
ここでは、プログラムの例としてパスワード入力を扱いましたが、SSH 接続を行うのであれば、通常は ~/.ssh/config
ファイルによる SSH キー設定 を用いた方がよいでしょう。