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

Linuxでコマンドを入力するときに対話式のコマンド入力を自動化する方法を記述していきたいと思います.

 

 

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

私の使っているUbuntuでは何故か頻繁にwi-tiのトラブルに見舞われる.
wi-fiをオンにしているにもかかわらず,一向に検出されない...といったことが頻繁に起きるのである.笑
こういった症状が発生する場合,大抵は下記コマンドを実行すれば解決するのだが,これをいちいちコンソールを開いて実行するのが非常に面倒くさいです...

シェルスクリプトを書いてショートカットキーから実行できるようにしたいのですが,このようなsudoの必要なコマンドに対してはパスワード入力が必要となってきます.
他にも,ssh接続やパスワード変更等の際に,必ず対話は発生すると思います.
このような何らかの対話が必要となってくるコマンドを自動化する方法について記述していきます.

 

 

expectコマンド

こういった対話式コマンドを実現するためにexpectというコマンドを使用します.
ubuntuの方でしたら下記コマンドでexpectコマンドをインストールできます.

 

 

expectコマンドの仕組み

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

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

処理の流れとしては,以下のようになります.
マシンにコマンドを送る(spawn) -> マシンからの返答 -> 返答の文字列に対してパターンマッチング(expect) -> マッチングの結果に応じてコマンドを送信(send)

 

 

サンプルコード

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

<コードの解説>

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

password=” ~ “
ここにパスワードを入れます.

command=” ~ “
コマンドを入力します.

expect -c ” ~ “
実際にexpectで対話コマンドを実行する部分になります.
コマンド “sudo service network-manager restart” を実行すると,
“[sudo] <username>のパスワード : ” という返答が来るので,sudoという文字列をパターンマッチングし,一致した場合にパスワーとを入力するといった仕組みになっています.入力の後には改行コード ‘\n’ も忘れずに入力します.
このとき,timeout[s]待ってもsudoという文字列とマッチする返答が得られなかった場合には処理を終えます.