expectで対話式のコマンドを自動化する

Linuxでコマンドを入力するときにパスワードの入力など、マシンとの対話式コマンドをしようすることがあると思います。

その対話を自動化する方法について記述していきたいと思います。

 

 

そもそもどうして自動化したいのか

私の使っているUbuntuでは何故か頻繁にwi-tiのトラブルに見舞われます。

wi-fiをオンにしており、ルータがすぐ近くにあるにも関わらず一向に検出されない。。。
といったことが私のPCでは頻繁に起ます。笑

こういった症状が発生する場合,大抵は下記コマンドでネットワークマネージャを再起動すれば解決するのですが、これをいちいちコンソールを開いて実行するのが非常に面倒くさいです。

そこで、このコマンドを自動化するシェルスクリプトを書いて、ショートカットキーから実行できるようにしようと思います。
このようなsudoの必要なコマンドに対してはパスワード入力が必要となってくるので、パスワードの入力も含め、自動化していきたいと思います。

このような事例の他にも、ssh接続であったり、apt-get updateなど、パスワードを入力する機会は多いと思いますので、そのような煩雑な処理をシェルスクリプトで自動化していきましょう!

 

 

expectコマンド

こういった対話式コマンドの自動化を実現するためにはexpectというコマンドを使用します。
ubuntuではapt-getでexpectコマンドをインストールすることができます。

確か、デフォルトでは入っていなかったと思います。

 

 

expectコマンドの仕組み

expectコマンドを使用する際に覚えておくコマンドは以下の通りです。

コマンド 説明
set timeout コマンドのタイムアウトの秒数を設定する(デフォルトでは10[s])
spawn コマンドを送る
expect マシンからの応答を読み取り、パターンマッチングを行う
send マシンの応答に対しての返答を行う

expectコマンドでの対話処理の流れとしては、以下のようになります。

  1. マシンにコマンドを送る(spawnコマンドによる処理)
  2. マシンからの返答
  3. 返答の文字列に対してパターンマッチング(expectコマンドによる処理)
  4. マッチングの結果に応じてコマンドを送信(sendコマンドによる処理)

 

 

サンプルコード

実際にサンプルコードを見て見ましょう。

<コードの解説>

timeout=10
タイムアウトの時間を設定します。
-1に設定した場合にはタイムアウトは行いません。

password=” ~ “
ここにパスワードを入れます。
後に、このpassword変数をsendコマンドにてマシンに入力しています。

command=” ~ “
実行したいコマンドを入力します。
(例えば、”sudo apt-get updateなど)

expect -c ” ~ “
実際にexpectで対話コマンドを実行する部分になります。
例えば、sudoつきで実行しなければならないコマンドを実行すると、”[sudo] <username>のパスワード : ” という返答が来るので、その返答に対して”sudo”という文字列でパターンマッチングをかけ、返答の中に”sudo”文字列が存在した場合にはパスワードをsendコマンドにて入力するといった仕組みになっています。

入力の後には改行コード ‘\n’ も忘れずに入力しましょう。
入力しないとパスワードの入力が終わっていないとみなされ、次に進めません。

また、timeout[s]待ってもsudoという文字列とマッチする返答が得られなかった場合には処理を終了します。

 

 

以上、expectコマンドの使い方でした。