対話型CLIコマンドをexpectで自動化する方法
Expectは、スクリプトに従って対話型プロンプトに自動的に応答するために使用できる無料でオープンソースのユーティリティです。このチュートリアルでは、最も使用されるLinuxディストリビューションにExpectをインストールする方法、対話型プロンプトに自動的に応答する方法、およびautoexpectを使用してExpectスクリプトを生成する方法について学びます。
このチュートリアルでは、あなたが学ぶことができることは:
- 最も使用されているLinuxディストリビューションにexpectをインストールする方法
- expectスクリプトを書く方法
- autoexpectを使用して、expectスクリプトを自動生成する方法
expectをインストールする
主要なLinuxディストリビューションのリポジトリにはexpectが用意されていますが、通常はデフォルトでインストールされていません。FedoraやRocky LinuxなどのRed Hat系のディストリビューションにこのユーティリティをインストールするには、dnfパッケージマネージャーを使用します。
sudo dnf install expect
Debianやそれに基づく他のディストリビューションにパッケージをインストールするには、代わりに次のコマンドを実行できます。
sudo apt-get update && sudo apt-get install expect
ExpectはArchlinuxの「Extra」リポジトリにも利用可能です。pacmanを使用してインストールできます。
sudo pacman -Sy expect
使用例を期待してください
特定のコマンドラインユーティリティやプログラムは、インタラクティブに動作できるだけでなく、ユーザーが専用のオプションを介して必要な引数を渡すことを可能にします。他の場合、さまざまな理由からそれらのオプションが欠けていることがあります。そこにexpectが便利になります。
専用のexpectスクリプトを作成することで、ユーザーの対話を必要とするコマンドの実行を自動化し、予想されるプロンプトに対して事前に定義された回答を提供できます。基本的な例をいくつか見てみましょう。ここでは、名前、国、メールアドレスなどの質問をするスクリプトを作成します。
#!/bin/bash
read -p "What is your name? " name
read -p "What is your country? " country
read -p "Enter your email address: " emailスクリプトは些細なもので、データ検証を行いませんが、私たちの目的には十分です。それを「prompts.sh」として保存し、実行可能な権限を与えます:
chmod +x prompts.sh
実行すると予想通り、要求された情報を提供するように促されます。
./prompts.sh
What is your name? Egidio
What is your country? Italy
Enter your email address: nomail@gmail.com
スクリプトによって作成された最初のプロンプトに回答し、「Enter」を押すと、次のプロンプトが表示される、という具合です。プロンプトの見た目がわかっているので、私たちはそれに自動的に回答する期待スクリプトを作成することができます。こちらです:
#!/bin/expect
spawn ./prompts.sh
expect "What is your name?" { send "Egidio\n" }
expect "What is your country?" { send "Italy\n" }
expect "Enter your email address" { send "nomail@gmail.com\n" }
expect EOF最初に注意すべきことは、私たちがスクリプトインタープリターとして /bin/expect を使用したことです。これは、スクリプトを expect プログラムに引数として渡さざるを得ないことを避けるためです(これはスクリプト内で使用できるコマンド名とは混同しないでください)。私たちの簡単なスクリプトでは、spawn、expect、および send の3つのコマンドを使用しました。
最初のもの、spawnは新しいプロセスを実行し、標準出力、標準入力、および標準エラーファイルディスクリプタを接続して、プログラムメッセージを解析し、スクリプト化されたアクションを実行できるようにします。
「expect」コマンドは、spawnコマンドで起動した実行可能ファイルの出力が特定のパターンに一致するまで待機します。上記の例では、一致は出力のどこにでも発生する可能性があります。コマンドの出力が「あなたの国は何ですか?」だった場合でも、パターンは一致します。より厳密な一致を強制するには、正規表現のアンカー「^」と「$」を使用することができます。これらはそれぞれ、データストリームの始まりと終わりに一致します。
出力がパターンに一致しない場合、タイムアウトが切れたら、expect コマンドが戻り、スクリプトの実行は次の命令に進みます。デフォルトのタイムアウトは 10 秒であり、“timeout” 変数に異なる値を割り当てることで変更できます:
set timeout 20
上記の例では、20秒のタイムアウトを設定しました。-1の値を使用すると、タイムアウトが完全に無効になり、expectは無限に待機します。一方、0の値は反対の動作を引き起こし、expectは全く待機しません。
最後に使用したコマンドはsendです。sendコマンドは、プロセスに文字列を送信します。デフォルトではフォーマットが適用されないため、提供した文字列に\n文字(行の終わり)を含めたことに注意してください。
スクリプトの最終行では、特定のメッセージの代わりにEOF(ファイルの終わり)でマッチしました。スクリプトをprompts.expとして保存し(「.exp」という拡張子はただの慣習です)、実行可能にします。最後に、これを起動します。こちらがその出力です:
./script.exp
spawn ./prompts.sh
What is your name? Egidio
What is your country? Italy
Enter your email address: nomail@gmail.com
autoexpectを使用して期待スクリプトを自動生成する
Autoexpectはexpectと一緒に付属するユーティリティで、対話型セッションの結果としてexpectスクリプトを生成するために使用できます。手動でexpectスクリプトを書く代わりに、autoexpectを使用してユーザーの対話を必要とするコマンドを実行できます。例えば:
autoexpect ./prompts.sh
引数としてautoexpectに提供したスクリプトは実行され、通常通り私たちの相互作用が必要です。しかし、スクリプトが終了すると、script.expというexpectスクリプトが生成されます。これを実行すると、私たちがインタラクティブに行った処理を再現します。
締めくくりの考え
このチュートリアルでは、対話型コマンドを自動化するために expect を使用する基本を学びました。spawn、expect、send コマンドを使用して expect スクリプトを書く方法の非常に基本的な例を見ました。最後に、autoexpect ユーティリティを使用して expect スクリプトを自動的に生成する方法も見ました。ここでは expect スクリプトを使用して達成できることの表面をかすめただけです。より深い知識のために expect マニュアルをご覧ください。
