autoexpect

セッションを監視することによりExpectスクリプトを生成する

autoexpect - セッションを監視することによりExpectスクリプトを生成する
autoexpect [ args ] [ program args... ]

autoexpectは、あなたとプログラムとの対話を監視し、 その対話を再現するExpectスクリプトを生成する。 直線的なスクリプトなので、 スクリプトを手作業で書くのに比べ相当な時間を節約できる。 たとえあなたがExpectのエキスパートだとしても、対話のより機械的な部分を 自動化するためにautoexpectを使うと便利であることが分かるだろう。 autoexpectの生成したスクリプトの一部をカットアンドペーストした方が ゼロから書き始めるよりとても簡単である。 そしてもしあなたが初心者だとしたら、Expectについて何も知らなくても autoexpectの起動方法を習うだけで用が足りるかもしれない。
autoexpectを使う最も簡単な方法は、 コマンドラインから引数なしで呼び出すことである。 デフォルトでシェルを起動する。 例: % autoexpect
プログラム名と引数が与えられるとautoexpectはそのプログラムを起動する。 例: % autoexpect ftp ftp.cme.nist.gov
一旦プログラムが起動されれば、対話は通常と変わらない。 あなたが起動したシェル(または、指定したプログラム)を終了すると autoexpectは新しいスクリプトを生成する。 デフォルトではscript.expファイルに書き込まれる。 -fフラグを使うとファイル名を指定することができる。
次はftp ftp.cme.nist.govを実行し、結果のExpectスクリプトを nistファイルへ格納する例である。

% autoexpect -f nist ftp ftp.cme.nist.gov
autoexpectが生成するスクリプトは動作が保証されている訳ではないという点を 理解しておくことが重要である。 なぜならば、確かな事柄や時々間違うことを推測しなければならないのだから。 しかしながら、通常はこれらの問題を特定し解決することはとても簡単である。 典型的な問題点は:
bu
タイミングの問題。 驚くほど多くのプログラム(rn, ksh, zsh, telnet, 等)やデバイス(例えばモデム) は、プロンプトの後の早すぎるキー入力を無視する。 もし特定の場所でスクリプトが切れてしまう場合は、先の送信の直前に 短いスリープの追加を試みよ。
生成されたスクリプトの先頭近くにあるforce_conservative変数を有効にする ことにより、この働きを全体にわたって強制的に行うことができる。 このconservativeモードでは、各々の文字送信の前に自動的に 短いポーズ(0.1秒)を入れる。 全てのプログラムに対してこの方法は有効である。
このconservativeモードは、スクリプトの実行がどれほど早いのかは気にせず、 ただタイミングの問題か否かを手っ取り早く確かめたいのなら便利である。 -cフラグを付けて実行すると同等のモードを強制することができる。
幸運にも、このようなタイミングの場所は稀である。 例えば、telnetはエスケープシーケンスを入力した後のみ文字列を無視する。 モデムは初回接続直後に文字列を無視するだけである。 また少数だがこの働きを無効にするスイッチを持つプログラムもある。 例えば、rnの-Tフラグはこの働きを無効にする。
次は、conservativeモードで実行する例である。

autoexpect -c
-Cフラグはconservativeモードを切り換えるためのキーを定義する。 次は、^Lを切り換えキーと定義し(non-conservativeモードで)実行する例である。 (注: ^Lはコントロール+Lを示す)

autoexpect -C ^L
次は、^Lを切り換えキーと定義しconservativeモードで実行する例である。

autoexpect -c -C ^L

bu
エコーの問題。 多くのプログラムが文字をエコーする。例えば、シェルに対して moreとタイプすると、autoexpectには以下のように見える:

you typed 'm', computer typed 'm', you typed 'o', computer typed 'o', you typed 'r', computer typed 'r',

そのプログラムに対する特有の知識が無いと、 エコーされた文字を待ってから、次の文字をタイプしているのかどうかを 知ることは困難である。 autoexpectは、文字列がエコーされていると見なすと、元々の対話手順のように 細切れに対話するのではなく、グループとして全てを一度に送信できると判断する。 このためスクリプトが読み易くなる。 しかし、本当にエコーを待ってから入力しなければならない場合には、 間違った動作となることが考えられる。

bu
変化の問題。 autoexpectは対話で生じたすべての文字をスクリプト内に記録する。 この事は、どの文字が重要でどの文字は置き換えられるかを判断できるため、 好ましいことである。
しかし一方では、実行する度に異なる出力を生じるコマンドを使う場合、 生成されたスクリプトは正しく動作しないかもしれない。 例えば、dateコマンドは常に異なる出力を生成する。 そのため、autoexpect実行中にdateコマンドを使うと、生成したスクリプトを 働かせるためには間違い無く修正が必要になるだろう。
-pフラグは、autoexpectをpromptモードにする。 このモードでは、autoexpectはプログラムの出力する最終行(普通はプロンプト) だけを記録する。 このモードは、上述のdateコマンドの問題や他のほとんどの変化の問題を扱う ことができる。
次は、promptモードで実行する例である。

autoexpect -p
-Pフラグはpromptモードを切り換えるためのキーを定義する。 次は、^Pを切り換えキーと定義し(non-promptモードで)実行する例である。 (注: ^Pはコントロール+Pを示す)

autoexpect -P ^P
次は、^Pを切り換えキーと定義しpromptモードで実行する例である。

autoexpect -p -P ^P
-quiet フラグは、autoexpectのメッセージ出力を非表示にする。
-Q フラグは、引用文字を定義する。 引用文字は、切り替えキーとして使われるためautoexpectが別の意味に取って しまう文字を入力するために使うことができる。
次は、引用文字と一緒に複数のフラグを定義する例である。 引用文字は、切り替えキーを文字通り入力する方法として提供される。

autoexpect -P ^P -C ^L -Q ^Q

Expectプログラムのための様式があるか否か分からないが、 明らかにautoexpectはどのような様式のモデルにも縛られるべきではない。 例えば、コンピュータ生成スクリプト用に意図された Expectプログラムの特徴を autoexpectは利用している。 だから、autoexpectによって生成されたかのようなスクリプトを 忠実に記述してみてはならない。
しかし一方では、autoexpectのスクリプトは価値のある事を示している。 例えば、autoexpectを通して実行することにより、 Tclスクリプトの中で使用する目的では、どのように文字列は引用されなければ ならないかを簡単に知ることができる。
Exploring Expect: A Tcl-Based Toolkit for Automating Interactive Programs by Don Libes, O'Reilly and Associates, January 1995.
Don Libes, National Institute of Standards and Technology
expectautoexpect は、パブリックドメインである。 これらのプログラムあるいは一部が使われたなら、 NISTと著者への謝辞を述べてもらいたい。