EXPECT(1) EXPECT(1)
名前
expect - 対話的なプログラムとのやりとりを自動化するプログラム, バージョ
ン 5
書式
expect [ -dDinN ] [ -c cmds ] [ -[f|b] ] cmdfile ] [ args ]
イントロダクション
Expect は、スクリプトの指示に従って、対話的なプログラムと"会話"するプロ
グ ラムである。以下のスクリプトに示すように、 Expect には、対話プログラ
ムからの期待されうる入力とそれに対する正しい応答を教えておく。インタ プ
リ タは分岐処理と高度な制御構造を提供し、対話プログラムへの指示を行なう
。さらに、必要な時にスクリプトから制御を奪って直接人間が指示を行ない 、
その後、制御をスクリプトへ戻すことができる。
Expectk は Expect と Tk の混合物である。 Expect であり、かつ、 Tk’s
wish であるかのように振舞う。 Expect は、C あるいは C++ (つまり、Tcl 以
外)から、直接使うこともできる。 libexpect(3)を参照。
"Expect"という名前は、uucpで有名になった send/expect の概念に由来する。
(kermitや他のモデム制御プログラムでも、この概念は使われている) し か し
、uucp とは違って Expect は一般化されているので、想像されるどんなプログ
ラムやタスクに対してもマクロコマンド(user-level command)として機能で き
る。 Expect は、同時に複数のプログラムと会話することができる。
Expect にできることの例をいくつか挙げておく:
· 電話代を払わずにログインできるようにコンピュータからあなたに
電話を掛け直させる。
· ゲーム(例えば rogue)を始める時に、最適なパラメタがもらえなか
った場合最適なパラメタがもらえるまで何度でもリスタートを行な
い、その後制御を人間に移す。
· fsckを走らせた時に現れる質問に、前もって決めておいた方針に従
って、 "yes", "no", "手入力"を切替えて、返答する。
· 他のネットワークや BBS(例えばMCI Mail, CompuServe)に接続した
時に自動的にメールの取り込み、発信を行なう。
· 環境変数、カレントディレクトリ、その他の情報を、rlogin, tel-
net, tip, su, chgrp などを行なった先へ持っていく。
こ れらの処理をシェルが行なえない理由はたくさんある (やってみればわかる
だろう)。全部 Expect ならできる。
一般に Expect は、プログラムとユーザーのやりとりが必要なプログラムを 走
ら せるときに役に立つ。大事なことは、このやりとりがプログラムの性格を持
っているということである。 Expect は、必要ならユーザーに制御を返すこ と
も できる(しかも、プログラムは中断されない)。同様に、ユーザーは制御をい
つでもスクリプトに返すことができる。
用法
Expect は、 cmdfile を読み込み、実行するコマンドのリストを得る。 Expect
は、#! 表記をサポートする OS で、先頭行に
#!/usr/local/bin/expect -f
と 書いておいて実行させることもできる。もちろん、パスは正確に Expect の
ある場所を指示していなければならない。 /usr/local/bin は、一例である。
-c フラグで、スクリプトを実行する前に、実行するコマンドを指示する。コマ
ン ドはシェルに壊されないようにクオートしておくべきである。このオプショ
ンは何回出てきても構わない。複数コマンドを指示した場合は、セミコロン で
連 結 さ れ た コマンドのように扱われる。コマンドは現れた順に実行される
。(Expectk では、 -command と書く)
-d フラグで、デバッグ情報出力を有効にする。基本的に内部のコマンド(例 え
ば expect や interact) の振舞いを報告する。このフラグは"exp_internal 1"
とスクリプトの先頭に書くのと同じことだが、さらに Expect のバージョン 番
号 も出力される。 ( strace コマンドは、命令をトレースするのに便利である
。 trace コマンドは、変数値をトレースするのに便利である。) (Expectk を
使う時は、このオプションは -diag と書く。)
-D フラグで対話型デバッガを有効にする。整数値が続かなければならない。値
が 0 でないか、C が押されると、次の Tcl 処理の前でデバッガに制御が移 る
。 ブレークポイントにかかった時や他のデバッグ命令を実行した時も、同じで
ある。デバッガについての情報がもっと欲しければ、 README や下記の関連 項
目を読むこと。 (Expectk を使っている時は、このオプションは -Debug)
-f フラグで、コマンドを読んでくるファイルを指示する。このフラグはあって
もなくても良いのだが、#! 表記と一緒に使うと引数からプログラム名を除ける
から、その場合意味がある。 (Expectk では -file)
デ フォルトでは、コマンドファイルがメモリに一度に読み込まれ、そこで実行
される。一行ずつコマンドファイルを読んだ方が望ましい場合もある。例え ば
、 標準入力はこのように扱った方が良い。強制的にこのモードを指定するには
、 -b フラグを指定する。 (Expectkでは、 -buffer) stdio のバッファリング
は 依然有効であるが、FIFO または stdin から読み込む場合は問題は起こらな
いはずであることに注意すること。
"-"がファイル名として渡されると、標準入力からスクリプトが読み込まれる。
(本当に"-"と言うファイルが読みたければ、"./-"と書くこと)
-i フラグを指示すると、 Expect はファイルからスクリプトを読まずに対話用
プロンプトを表示する。 exit コマンドか、EOF を受けるとシェルを終了す る
。 詳細については interpreter (下記) を参照のこと。 -i を指定した場合に
は、コマンドファイルも -c も指示されなかったものとして実 行 さ れ る 。
(Expectkでは -interactive)
-- は、オプションの終りを区切るのに用いられる(省略可能)。これは、あなた
がオプションタイプの引数を Expect に解釈させないで、スクリプトにその ま
ま渡したい時に役に立つ。 #! 行にこれを置いて、Expect にオプションとして
解釈させないようにすることができて便利た。
例えば、以下のように書くと(スクリプト名も含めて)オリジナルの引数は、 変
数 argv に残される。
#!/usr/local/bin/expect --
#! 行に引数を加えると、通常の getopt(3) や execve(2) ではその引数が見え
てしまうことに注意すること。
-N フラグを用いない限り、ファイル $exp_library/expect.rc が(あれば)自動
的 に 実 行 さ れ る。 (Expectk では、 -NORC) -n フラグ (Expectk では、
-norc) を用いない限り、続いて、ファイル ~/.expect.rc が、自動的に実行さ
れ る。環境変数 DOTDIR が定義されていれば、そこが .expect.rc のあるディ
レクトリとして扱われる。
この二つのrcファイルの実行より先に -c フラグで指示されたコマンドが実 行
される。
-v フラグを指示すると、バージョン番号を表示して終了する。 (Expectkでは
、-version)
オプション args は、リストに変換されて、変数 argv に保存される 。 argc
は、argv のリスト長(要素の数)に設定される。
argv0 は、スクリプト名に設定される(スクリプトを使っていなければ、バイナ
リの名前になる)。例えば、以下のスクリプトを実行すると、スクリプト名と最
初の引数3つを表示する:
send_user "$argv0 [lrange $argv 0 2]\n"
コマンド
Expect は、 Tcl (Tool Command Language)を使用している。 Tcl は、制御フ
ロー(例えば if, for, break)、式評価、および、再帰やプロシジャ定義等他の
いくつかの機能を提供する。ここで使われているのに定義がないコマンド(例え
ば、 set, if, exec) は、Tcl コマンドである。(tcl(3)を参照)。 Expect は
、 以下に記述する追加コマンドをサポートする。記述がない場合は、そのコマ
ンドは空文字列を返す。
コマンドはアルファベットの列なのですぐにわかると思うが、新しいユーザ ー
は 、 spawn, send, expect, interact, が、この順で並んでいるところを読み
始めた方が理解しやすいと気がつくかも知れない。
この言語(Expect と Tcl の両方)へのイントロダクションとしては、 "Explor-
ing Expect"という本(関連項目を参照)がベストである。このマニュアルページ
はリファレンスとして書いているので、含まれている例は非常に限られてい る
。注意すること。
こ のマニュアルページで、大文字の"E"で"Expect"とあれば、それは、 Expect
プログラムを指し、一方小文字の"e"で"expect"とあれば、それは、 Expect プ
ログラムに実装されている expect コマンドを指す。注意すること。
close [-slave] [-onexec 0|1] [-i spawn_id]
カ レントプロセスへのコネクションをクローズする。ほとんどの対話型
プログラムが標準入力の EOF を検出し exit する。それゆえ 、 close
は そのプロセスを kill するのにも通常充分である。 -i フラグを指示
すると、続く spawn_id を持つプロセスをクローズする。
expect と interact は両方とも、カレントプロセスが exit した時点を
検 出 し て 、明示しなくても close を実行する。しかし、"exec kill
$pid" などのように、あなたがプロセスを kill しているなら、明示 的
に close を呼ぶ必要がある。
-onexec フラグを指示すると、新しい spawn が起きた時またはプロセス
が重ねられた時に前の spawn を閉じるべきかどうかを指示することがで
きる。前の spawn id で開いたままにしておきたければ、値 0 を用いる
。 0 でない整数を指示すると、新しいプロセス中では前の spawn は ク
ローズされる (デフォルト)。
-slave フラグを指示すると、その spawn id の抱えているスレーブの
spawn もクローズする。 ("spawn -pty"を参照) コネクションがクロ ー
ズされると、スレーブはオープン状態であってもクローズされる。
コ ネクションのクローズが明示されていたか否かに全然関わりなく、関
係するカーネルプロセススロットをクリアしてしまいたければ 、 wait
を呼ぶこと。 close は、 wait を呼ばない。プロセスへのコネクション
をクローズすると、そのプロセスが exit するという保証がないから で
ある。もっと知りたければ、 wait の項を参照すること。
debug [[-now] 0|1]
は 、Tcl デバッガを制御する。デバッガにより、ステップ実行、ブレー
クポイントの設定などが行なえる。
引数がない場合、デバッガが走っていれば 1 を、そうでなければ 0 を
返す。
引 数が 1 なら、デバッガが起動される。引数が 0 なら、デバッガが停
止する。引数 1 の前に -now フラグがあれば、デバッガは即座に起動さ
れる(つまり、 debug コマンドそのものの途中で)。そうでなければ、デ
バッガは次の Tcl コマンドから起動される。
debug コマンドはトラップを変更しない。 -D フラグをつけて起動さ せ
た場合とはそこが違う(上記参照)。
デバッガについては、README ファイルと関連項目を参照すること。
disconnect
fork されたプロセスを端末から切り離す。バックグラウンドで動作は続
く。プロセスは可能であれば自分自身のプロセスグループを与える。 標
準入出力は、/dev/null にリダイレクトされる。
以 下の断片は、 disconnect を使って、バックグラウンドでスクリプト
の実行を続ける。
if {[fork]!=0} exit
disconnect
. . .
以下のスクリプトは、パスワードを読んで、一時間毎にパスワードを 要
求 するプログラムを実行する。スクリプトはパスワードを読み込んでい
るので、タイプするのは一回だけで済む。 (パスワードのエコーを避 け
る方法については、 stty コマンドを参照)
send_user "password?\ "
expect_user -re "(.*)\n"
for {} 1 {} {
if {[fork]!=0} {sleep 3600;continue}
disconnect
spawn priv_prog
expect Password:
send "$expect_out(1,string)\r"
. . .
exit
}
シ ェ ルの非同期実行(&)時に disconnect を用いる利点は、 Expect が
disconnect の前に端末情報を保存しておいて、後で新しい pty にそ の
パラメタを適用できる点にある。 & を使っていて Expect が制御を受け
とって disconnect されてしまうと、端末情報を読み込むことはでき な
い。
exit [-opts] [status]
Expect を exit させるか、そのための準備を行なう。
-onexit フラグは、続く引数を exit ハンドラとして用いる。引数がな
ければ、exit ハンドラは何もしない。
-noexit フラグを指定すると Expect は、exit の準備をして OS へ制御
を 返す直前に停止する。ユーザーの定義した exit ハンドラは、Expect
自身の内部ハンドラと同じように実行される。それ以上 Expect のコ マ
ン ド が 実 行 さ れるべきではない。あなたが他の Tcl Extension を
Expect につけている場合にこの機能は意味がある。 Expect の exit が
も う一度呼び出されると(こういう場合も起こり得る)、ハンドラは処理
を返さない。
exit する際に、全ての spawn されたプロセスへのコネクションはク ロ
ーズされる。クローズは EOF 検出によって行なわれる。 exit は、普通
の exit(2) が行なう以上のことはしない。それで、spawn されたプロセ
ス が EOF をチェックしない場合、そのプロセスは走り続ける。(spawn
されたプロセスへ送られたシグナルを判断するといったことには複数 の
条 件が関わってくる。これらは、システム依存であり、典型的な動作は
各システムの exit(3) のドキュメントに記述されている。)
status (指定がないときは、0 )は、 Expect の、終了ステータスとして
シ ステムに返される。 exit は、スクリプトの終りに達すると、書いて
いなくても実行される、
exp_continue [-continue_timer]
exp_continue コマンドは expect 自身に待っていた値が来なかった時の
ように、expect の実行を続ける。デフォルトでは exp_continue は時間
切れタイマーをリセットする。 -continue_timer フラグはタイマーを再
実行しないようにする。 (より詳細な情報は expect を参照のこと。)
exp_internal [-f file] value
value がゼロでなければ、以降のコマンドの診断情報を Expect 内部の
stderr に送るようになる。 value に0を指定するとこの出力は止まる。
こ の診断情報には、受けとったすべての文字と、現在の出力とパターン
をマッチさせる全試行が含まれる。
file オプションを指定すると、すべての通常および診断出力がそのファ
イルに出力される。( value の値とは無関係に)。すでにオープンされて
いる診断出力ファイルは、すべてクローズされる。
-info フラグは、最後に指定された info フラグでない引数の内容を 返
す。
exp_open [args] [-i spawn_id]
元の spawn id に結びつけられたファイル ID を返す。そのファイル ID
は、Tcl の open コマンドでオープンした時と同様に扱える 。 (spawn
id は、もう使われるべきでない。 wait も実行すべきではない。)
-leaveopen フラグは、spawn id をオープンしたままにしておく。 wait
が、その spawn id に対して実行されねばならない。
exp_pid [-i spawn_id]
現在の spawn されたプロセスのプロセス ID を返す。 -i フラグを指示
すると、与えられた spawn id に対するプロセスの ID を返す。
exp_send
send のエイリアス。
exp_send_error
send_error のエイリアス。
exp_send_log
send_log のエイリアス。
exp_send_tty
send_tty のエイリアス。
exp_send_user
send_user のエイリアス。
exp_version [[-exit] version]
は 、スクリプトが現バージョンのExpectで動くことを確かめる時に役に
立つ。
引数がなければ、 Expect の現在のバージョンを返す。このバージョ ン
は あなたのスクリプト内で設定しても良い。あなたが最近のバージョン
に入った機能を使わないのであれば、もっと前のバージョンを指定す る
ことができる。
バージョンはドットで区切られた 3 つの番号である。最初の番号は、メ
ジャー番号である。違うメジャー番号の Expect 用に書いたスクリプ ト
は、まず動かない。 exp_version は、メジャー番号がマッチしないとエ
ラーを返す。
2 番めの番号はマイナー番号である。使っている Expect よりマイナ ー
番 号がより大きい Expect 向けのスクリプトは、新機能の使用未使用に
よるが、動かないかも知れない。 exp_version はメジャー番号がマッチ
し てもマイナー番号が使っている Expect のバージョンより大きいとエ
ラーを返す。
3番めの番号は、バージョン比較には使われない。しかし、文書の更新や
プ ログラムの最適化が行なわれて、 Expect のディストリビューション
が更新されると、番号が増えていく。新しいマイナーバージョンが設 定
される度に、0 にリセットされる。
-exit フラグをつけると、バージョンが合わなかった時に Expect はエ
ラーを表示し exit する。
expect [[-opts] pat1 body1] ... [-opts] patn [bodyn]
は、spawn されたプロセスの出力がパターンのどれかにマッチするか 、
指 定された時間が経過するか、enf-of-file を見つけるか、のいずれか
が成立するまでウェイトする。最後の body が空なら、それは省略で き
る。
一番最後に実行された expect_before コマンドのパターンが、どのパタ
ーンより先にチェックされる。一番最後に実行された expect_after コ
マンドのパターンが、どのパターンより後にチェックされる。
expect 全体への引数が 1 行に収まらなかった場合は、引数を"ブレー
ス"することで、各行の終りにバックスラッシュをつけるのを避けること
ができる。この場合、ブレースしたにもかかわらず通常の Tcl 展開が発
生する。
もし、パターンがキーワード eof であれば、end-of-file 発見時に処理
が実行される。もし、パターンがキーワード timeout であれば、タイム
アウトが発生した時に処理が実行される。 timeout キーワードが使われ
な かった場合、タイムアウト時にはなにもしない。デフォルトタイムア
ウトは 10 秒である。設定することもできる。例えば 30 秒と設定し た
け れば、"set timeout 30"を実行すること。タイムアウトさせないため
には、値 -1 を設定する。もし、パターンがキーワード default であれ
ば、タイムアウトか end-of-file のいずれかで処理が実行される。
パ ターンにマッチすれば、処理は実行される。 expect は、行なった処
理(関連するブレース内の処理)の結果を返す。 (パターンにマッチし な
か った時は、空文字列を返す。) 複数のパターンにマッチした場合、最
初にマッチしたパターンに対応する処理が実行される。
対話型プログラムからの新しい出力が Expect に届くたびに、リスト さ
れ ている順にパターンとの比較が行なわれる。それゆえ、マッチすべき
ものがないことを確認するために、プロンプトのように来ることがわ か
っ ているパターンを用意することができる。プロンプトがない場合には
、(あなたが手で打つ時に判断しているように) timeout を用いなければ
ならない。
パターンは 3 通りに書ける。デフォルトは、Tcl の string match コマ
ンドの書式である。(このパターンはグロブで参照される C-shell の 正
規 表現に似ている。) -gl フラグは、他のマッチからパターンを保護す
るのに使う。 "-"で始まるパターンは、この方法で保護すべきである 。
("-" で始まる文字列は将来の拡張で、オプションとして使われるかも知
れないから)
例えば、以下の断片はログインの成功を監視する。 (abort はスクリ プ
トのどこか他の場所で定義されていると仮定している。注意すること。)
expect {
busy {puts busy\n ; exp_continue}
failed abort
"invalid password" abort
timeout abort
connected
}
4番めのパターンにはスペースが含まれているのでクオートが必要である
。 アクションとパターンを分離するセパレータでないことを指示する必
要がある。 (3番めと4番めの)ように同じアクションを持つリクエストも
並 べて書く必要がある。これは、正規表現パターンを用いることで回避
できる(下記参照)。グロブスタイルパターンについてもっと情報が欲 し
ければ、Tcl のマニュアルを読むこと。
正 規表現パターンは、Tcl の regexp ("regular expression"の短縮)コ
マンドで定義される文法に従う。 regexpパターンは、 -re フラグで 始
める。前の例を、regexp で書き直すと、こうなる。:
expect {
busy {puts busy\n ; exp_continue}
-re "failed|invalid password" abort
timeout abort
connected
}
ど ちらのパターンのタイプも、"固定されていない"。どういう意味かと
いうと、文字列全体にマッチする必要はなくて、文字列のどこでもマ ッ
チすれば良いということである。^ が先頭にマッチする。 $ が末尾にマ
ッチする。文字列の末尾にマッチさせなければ、spawn されたプロセ ス
か らエコーされた文字列の途中で切り上げてレスポンスを返せることに
注意すること。正しく処理が実行されていても、出力は不自然に見え る
可能性がある。それで、文字列の終りの文字を正確に記述できるなら、$
を使うことを勧める。
多くのエディタでは、^ と $ は行頭、行末に正確にマッチする。しかし
、expect は行指向ではないので、(行ではなく)データの始まりと終りに
マッチする。 ("EXPECTヒント"内の、バッファリングの消化不良に関 す
る部分を参照のこと)
-ex フラグは、"正確に(exact)"指示された文字列にマッチする。 * や
^ などの解釈は行なわれない。(ただし、通常の Tcl 展開は行なわれる)
。 Exact パターンは常に固定されている。
-nocase フラグは、小文字が含まれている場合に大文字に変換してから
マッチさせる。パターンには影響しない。
出力を読んでいて、2000 バイトを超えてしまったデータは"忘れられる"
。この動作は、 match_max 関数で変更できる。 (極端に大きな値はパタ
ーンマッチの性能を低下させることに注意するこ と 。) patlist に
full_buffer を指定すると、 match_max バイト以上のデータを受けてパ
ターンマッチしなかったときに、処理が実行される。 full_buffer キー
ワ ードの有無に関わらず、忘れられたデータは expect_out(buffer) に
保存される。
patlist に、キーワード null を指定すると、ヌル文字が許可 さ れ (
remove_nulls コマンドを通して)、ヌル文字(ASCII 0)にマッチする。
glob や regexp では 0 バイトにマッチすることができない。
パターン(あるいは、eol, full_buffer)にマッチすると、マッチした 部
分 の 文 字 列 か 、 そ の 前 の マ ッ チしなかった文字列が、変数
expect_out(buffer) に保存される。
9 個までのマッチした部分文字列は、変数 expect_out(1,string) か ら
expect_out(9,string) に保存される。 -indices フラグをパターンの前
で指定すると、マッチした部分文字列の開始位置と終了位置が( lrange
の 引 数 と し て 使 え る 形 で) 、 変 数 expect_out(X,start) と
expect_out(X,end) に保存される。 X は数字で 0 〜 9 まで。 0 は パ
タ ー ン 全 体 が マ ッ チ し た 部分を指示する。例えば、プロセス
が"abcdefgh\n"を出力し、以下の形:
expect "cd"
で受けると、以下の文を実行したのと同じ結果となる。
set expect_out(0,string) cd
set expect_out(buffer) abcd
この時、"efgh\n"は出力バッファに残る。プロセス が"abbbcabkkkka\n"
を出力し、以下の形:
expect -indices -re "b(b*).*(k+)"
で受けると、以下の文を実行したのと同じ結果になる。
set expect_out(0,start) 1
set expect_out(0,end) 10
set expect_out(0,string) bbbcabkkkk
set expect_out(1,start) 2
set expect_out(1,end) 3
set expect_out(1,string) bb
set expect_out(2,start) 10
set expect_out(2,end) 10
set expect_out(2,string) k
set expect_out(buffer) abbbcabkkkk
こ の時、"a\n"は出力バッファに残る。パターン"*" (と -re ".*")は、
プロセスからのデータがさらに来ない限り、出力バッファをフラッシ ュ
しない。
通 常、マッチした出力は Expect の内部バッファから、切り捨てらる。
この動作は、 -notransfer フラグで抑止することができる。このフラグ
は、スクリプトを試している時に役に立つ(そして、"-not"と略記しても
良い)。
マッチした出力を送って き た プ ロ セ ス へ の spawn id は 、
expect_out(spawn_id) に保存される。
-timeout フ ラ グ は、この expect コマンドの中の timeout 時刻を
timeout 変数でなく指示された値に設定する。
デフォルトでは、パターンはカレントプロセスからの出力にマッチさ せ
る のだが、 -i フラグを設定すると、指定された spawn_id リストに対
応するプロセス群からの出力にマッチさせることができる。(次の -i で
の指定があるまで有効である。) spawn_id リストは、スペースで区切っ
た spawn_id のリストか、そのような値を持つ変数への参照でなくて は
ならない。
例えば、以下の例はカレントプロセスからの"connected"と $proc2 と言
う名前の spawn_id からの"busy","failed","invalid password" を待ち
受ける。
expect {
-i $proc2 busy {puts busy\n ; exp_continue}
-re "failed|invalid password" abort
timeout abort
connected
}
大 域変数 any_spawn_id の値は、今の expect コマンド内で -i フラグ
を指示した spawn_id の全てにマッチさせるために使われる。 -i フ ラ
グ をパターンなしで指定すると(すなわち、別の -i が直後に続くと)、
any_spawn_id で指定された、同じ expect コマンド内の他のパターンに
対して、有効になる。
-i フラグには、グローバル変数の名前を指定することもできる。その場
合、その変数は、spawn id のリストである。変数は変わるたびに読み直
される。こうすることで、コマンドが実行されている間に I/O ソースを
変更することができる。この方法で指定 さ れ る spawn id を" 間
接(indirect)" spawn id と呼ぶ。
break や continue な ど の アクションは、制御構造(すなわち、
for,proc )内で通常通りの振舞いをする。
exp_continue コマンドは、 expect ループから抜けるような状況で実行
を続けさせる。
ループを書いたり、expect コマンドを繰り返すことを避ける時に便利で
ある。以下の例はログインを自動化するコードの断片である。 exp_con-
tinue によって、(再びプロンプトを探すための)2 つめの expect コマ
ンドを書かなくて済んでいる。
expect {
Password: {
stty -echo
send_user "password (for $user) on $host: "
expect_user -re "(.*)\n"
send_user "\n"
send "$expect_out(1,string)\r"
stty echo
exp_continue
} incorrect {
send_user "invalid password or account\n"
exit
} timeout {
send_user "connection to $host timed out\n"
exit
} eof {
send_user \
"connection to host failed: $expect_out(buffer)"
exit
} -re $prompt
}
例えば、以下の断片は既に自動化されているユーザーガイドへのやり と
り を補助する。この場合、端末は raw モードになる。ユーザーが’+’を
押すと変数がインクリメントされる。 "p"が押されると、プロセスへ 復
帰情報が送られる。おそらくは同じように"i"が押されると、スクリプト
から制御を奪い、ユーザーからの制御が行なえる。どの場合も exp_con-
tinue コマンドが、今の expect に、処理を行なわせた後再びパターン
マッチさせている。
stty raw -echo
expect_after {
-i $user_spawn_id
"p" {send "\r\r\r"; exp_continue}
"+" {incr foo; exp_continue}
"i" {interact; exp_continue}
"quit" exit
}
デフォルトでは、 exp_continue は、タイムアウトタイマーをリセッ ト
す る 。 タ イ マを再開させるには、 exp_continue コマンドに -con-
tinue_timer フラグをつける。
expect_after [expect_args]
は、 expect_before と同様の動きをするが、 expect と expect_after
の 両方にマッチした場合、 expect のパターンが使用される点が異なる
。より詳しい情報は、 expect_before コマンドの項を参照のこと。
expect_background [expect_args]
は、 expect と同じ引数をとるが、その場で復帰する。パターンは新 し
い デ ータが届くたびにチェックされる。パターン timeout と default
は、 expect_background には、意味がないし、無視される。 expect と
同 様 に 、 expect_background コ マ ン ド は expect_before や
expect_after パターンを使える。
expect_background アクションが、評価される時、同じ spawn id を 持
つ バックグラウンドプロセスはブロックされる。アクションが完了する
と、プロセスがアンブロックされる。バックグラウンドプロセスがブ ロ
ッ ク されている間は、 (フォアグラウンドの) expect で、同じ spawn
id に接続することができる。逆に、 expect_background がブロック さ
れ て い ない間は expect することができない。特定の spawn id への
expect_background は、同一 spawn id への新しい expect_background
を指定すると削除される。パターンをつけない expect_background を指
定することで、バックグラウンドでパターンマッチさせることをやめ さ
せられる。
expect_before [expect_args]
は expect と同じ引数をとるが、その場で復帰する。もっとも最近、同
じ spawn id に対して expect_before で使われたパターン・アクション
の ペアが、続く expect コマンドに対して使用される。パターンがマッ
チすると、 expect コマンドにマッチした時と同じように動作する。 処
理 は 、その expect のコンテキストで行なわれる。 expect_before と
expect の両方のパターンにマッチした場合、 expect_before のパタ ー
ンが使われる。
パターンが指示されなかった場合、spawn id はどのパターンでもチェッ
クされない。
-i フラグをさらに指定しない限り、 expect_before パ タ ー ン は 、
expect_before が実行された時に定義されたパターンにマッチする。
-info フラグは expect_before から、マッチパターンの現在の状態を復
帰させる。デフォルトでは、現在の spawn id に報告する。オプショ ン
の spawn id を指定することもできる。例えば、
expect_before -info -i $proc
た った一つの spawn id 指定だけが許される。-indirect フラグで、直
接 spawn id を抑止し、間接的な指定から得られるidを指示する。
spawn id を指示する代わりに、"-all"フラグを使って、全て の spawn
id に "-info" の報告をさせることができる。
-info フラグを使った時の出力結果は、expect_before への引数として
再利用できる。
expect_tty [expect_args]
は、 expect と似た動きをするが、文字列を /dev/tty (すなわち、ユー
ザ ーからのキー入力) から読み込む。デフォルトでは、cooked mode で
読み込まれるので、行はリターンで終らなければならない。そうしな い
と expect が読めない。この動きは、 stty を使って変えられる。 (下
の stty コマンドを参照)
expect_user [expect_args]
は expect と似た動きをするが、文字列を stdin(すなわち、ユーザーか
ら のキー入力) から読み込む。デフォルトでは、cooked mode で読み込
まれるので、行はリターンで終らなければならない。そ う し な い と
expect が読めない。この動きは、 stty を使って変えられる。 (下の
stty コマンドを参照)
fork は、新しいプロセスを作る。この新しいプロセスは、現在の Expect プ
ロセスの正確なコピーである。成功すると fork は 新しい(子)プロセス
に 0 を返し、親プロセスに 子プロセスのプロセスIDを返す。失敗する(
ス ワップ、メモリなどのリソース不足か?)と、 fork は、親プロセスに
-1 を返す。新しい子プロセスは作成されない。
フォークされたプロセスは、 exit コマンドで ext できる。元のプロセ
ス と同様である。フォークされたプロセスはログファイルを作っても良
い。多くのプロセスでデバッグもログもできなければ、結果、混乱す る
だけである。
pty のインプリメンテーションの中には、複数の読み手と書き手が一瞬
でもあれば、混乱するものがある。それで、プロセスを spawn する前に
は fork しておくのが一番安全である。
interact [string1 body1] ... [stringn [bodyn]]
は 、現プロセスの制御をユーザーに渡す。結果、現プロセスに送られた
キーストロークと現プロセスの標準出力と標準エラー出力が復帰する。
string と body の組が、引数として指示できる。(デフォルトでは、 文
字 列 は 現 プロセスには送られない) 最後の body がないと、 inter-
preter コマンドが実行される。
interact コマンド全体への引数が一行に収まらない場合、"brace"す る
こ とで各行の終りにバックスラッシュを入れるのを避けることができる
。この場合、Tcl の展開はブレースしてあっても起こる。
例えば、以下のコマンドは続く string body の組と対話する。 : ^Z が
押 されると Expect はサスペンドする。 ( -reset フラグは、端末モー
ドを復旧させる。) ^A が押されると、ユー ザ ー に は"you typed a
control-A"が返る。
$ が 押 さ れ ると、ユーザーには日付が返る。 ^C が押されると、
Expect は、exit する。 "foo"が入力されると、ユーザーに "bar" が返
る。 ~~ が押されると、 Expect インタプリタは、対話モードになる。
set CTRLZ \032
interact {
-reset $CTRLZ {exec kill -STOP [pid]}
\001 {send_user "you typed a control-A\n";
send "\001"
}
$ {send_user "The date is [exec date]."}
\003 exit
foo {send_user "bar"}
~~
}
string と body の組で、string が引数として並べられた順に比較され
る。部分的にマッチした文字列は、残りが到着するまで送られて来な い
。 何文字かさらに打ち込まれて、マッチが可能になると、今のマッチを
判断するためにだけ使われて他のマッチを始めることはしない。それ ゆ
え 、部分的にマッチしている文字列のマッチが完了するのは遅れること
がある。部分的にはマッチするが最終的にはマッチしない文字列の場 合
などである。
デフォルトでは、ワイルドカードを含まないマッチは、exactとなる。 (
expect コマンドがデフォルトでグロブスタイルのパターンを用いるのと
は 対照的に。) -ex フラグは、パターンをプロテクトするのに使える。
interact フラグがそうするように。パターンが"-"で始まる場合、こ の
方法で保護できる。 ("-"で始まる文字列は全て将来のオプションとして
予約されている。)
-re フラグは、正規表現スタイルのパターンとして文字列を解釈する 。
こ の 場 合 、 マッチした部分文字列は interact_out に保存される。
expect が、その出力を変数 expect_out に保存するのと似たようなもの
である。 -indices フラグも同じようにサポートされる。
パターン eof は、end-of-file にマッチした場合にアクションを実行す
る。複数に分かれた eof パターンには -output フラグが続いても良 い
。その場合、出力が書かれている間に eof が検出されるとアクションを
実行する。 eof のデフォルトアクションは"return"である。それ で 、
interact は、EOF を見つけると復帰する。
timeout パターンは、(秒で表現された)タイムアウトにマッチし、アク
ションを実行する。 timeout パターンは、最後に指示されたプロセスに
適用される。タイムアウトにはデフォルトの値はない。(expect内で使わ
れる)特殊な変数"timeout"は、このタイムアウトと関係しない。
例えば、以下の記述は一時間以上タイプしなかったユーザーを自動的 に
ログアウトさせる。その前にシステムから頻繁にメッセージを受けとる:
interact -input $user_spawn_id timeout 3600 return -output \
$spawn_id
パターン null と nulls は、( remove_nulls コマンドを通して)、アス
キ ーの 0 にマッチした場合にアクションを実行する。 glob や regexp
で 0 バイトにマッチさせることはできない。
このパターンの前に -iwrite フラグ を つ け る と 、 変 数 inter-
act_out(spawn_id) にパターン(あるいはeof)にマッチした spawn_id が
設定される。
break や continue といったアクションは、制御構造 (すなわち、 for
や proc )の中で、通常通りに動く。しかし、 return は、interact を
呼出元に復帰させる。一方、 inter_return は、 interact をその呼 び
だ し 元 内 に 復 帰させる。例えば、"proc foo" は interact を呼ぶ
。interact が、さらに、 inter_return を実行すると proc foo が復帰
す る。(これは、 interact が、 interpreter を呼んで return とタイ
プすると、そのinteractは継続するが、 inter_return すると、その 呼
出元に復帰してしまうということである。)
interact の間 raw モードが使用されるので、全ての文字が現プロセス
に渡される。現プロセスがジョブコントロールシグナルを捕まえなけ れ
ば 、ストップシグナル(デフォルト^Z)で停止する。再スタートするには
、制御シグナルを送る。("kill -CONT
Copyright(C) linux-cmd.com All Rights Reserved. Author Takayuki Yukawa