other versions
| EXPECT(1) | General Commands Manual | EXPECT(1) |
名前¶
expect - 対話的なプログラムとのやりとりを自動化するプログラム, バージョン 5書式¶
expect [ -dDinN ] [ -c cmds ] [ -[f|b] ] cmdfile ] [ args ]イントロダクション¶
Expect は、スクリプトの指示に従って、対話的なプログラムと"会話"するプログラムである。 以下のスクリプトに示すように、 Expect には、対話プログラムからの期待されうる入力とそれに対する正しい応答を 教えておく。インタプリタは分岐処理と高度な制御構造を提供し、 対話プログラムへの指示を行なう。 さらに、必要な時にスクリプトから制御を奪って直接人間が指示を行ない、 その後、制御をスクリプトへ戻すことができる。- •
- 電話代を払わずにログインできるようにコンピュータからあなたに電話を掛け直させる。
- •
- ゲーム(例えば rogue)を始める時に、最適なパラメタがもらえなかった場合 最適なパラメタがもらえるまで何度でもリスタートを行ない、その後制御を人間に移す。
- •
- fsckを走らせた時に現れる質問に、前もって決めておいた方針に従って、 "yes", "no", "手入力"を切替えて、返答する。
- •
- 他のネットワークや BBS(例えばMCI Mail, CompuServe)に接続した時に 自動的にメールの取り込み、発信を行なう。
- •
- 環境変数、カレントディレクトリ、その他の情報を、rlogin, telnet, tip, su, chgrp などを行なった先へ持っていく。
用法¶
Expect は、 cmdfile を読み込み、実行するコマンドのリストを得る。 Expect は、#! 表記をサポートする OS で、先頭行に#!/usr/local/bin/expect -f
#!/usr/local/bin/expect --
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, が、この順で並んでいるところを読み始めた方が理解しやすいと 気がつくかも知れない。- 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_continue
によって、(再びプロンプトを探すための)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_continue コマンドが、今の 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 コマンドに -continue_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 がないと、 interpreter コマンドが実行される。
- 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 フラグをつけると、 変数 interact_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 <pid>"とか打って)。 本当に SIGSTOP をプロセスに送りたいなら、csh を spawn してその上で プロセスを起動すること。 そうでなくて、 Expect そのものに SIGSTOP を送りたいなら、インタプリタを呼び出して (普通はエスケープ文字)、その後 ^Z を打つこと。
- string bodyのペアは、インタプリタに入ってコマンドを対話的に実行するのを 避けることを簡単に書くのに使われる。 前の端末モードが、その body を実行する間使用される。
- 実行速度を上げるには、デフォルトでアクションが raw モードで動くように する。 -reset フラグは、端末の持っているモードをリセットする。そうしなければ、 その前に行なった interact コマンドの端末モード(cooked モードとか)が保持される。 モードが切り替わった時に、それまで打っていた文字が消えてしまうことが あるので注意すること。(システムによっては、そういう不幸な仕様をした 端末ドライバが動いている。) -reset を使うのは、アクションが cooked モードでしか動かない場合だけである。
- -echo フラグは、一文字づつパターンにマッチする文字を返す。これは、 ユーザーが打つ文字に部分的にマッチしなければならない場合に有効である。
- パターンはエコーされたがマッチには失敗した場合、文字列は、spawn
された
プロセスに送られる。それから、spawn
されたプロセスが文字列を表示し、
ユーザーは文字列を二度見る。
-echo
は、ユーザーがパターンを完成させてくれそうもない場合にだけ有効であろう。
例えば、以下は
rftp(リカーシブ ftp
スクリプト)からの抜粋だが、ユーザーが
~g, ~p, ~l
を打つとカレントディレクトリから再帰的(リカーシブ)に
get, put, list する。通常の ftp
ではこれらの操作ができない。間違って
~ を 打つか、~
の後を間違えた場合、その文字列を無視するようになっている。
interact { -echo ~g {getcurdirectory 1} -echo ~l {getcurdirectory 0} -echo ~p {putcurdirectory} }-nobuffer フラグは、文字が読まれる度に、その文字をマッチへ送る。このフラグは、パターンをエコーバックする時に有効である。 例えば、以下は誰かが(ヘイズモデムを)ダイアルするのを監視するのに 使われる。"atd"が見える度にスクリプトが残りのラインをログする。proc lognumber {} { interact -nobuffer -re "(.*)\r" return puts $log "[exec date]: dialed $interact_out(1,string)" } interact -nobuffer "atd" lognumber
- interact の間、前に使った log_user は無視される。特に、 interact は、その出力を記録される(標準出力に送られる)。 というのは、ユーザーはエコーバックのない状態でキーを打ちたくはない だろうと考えるからである。
- -o フラグは、現プロセスの出力に key body ペアの key を結びつける。 こんな場合に便利である。例えば、telnet セッション中に望まない文字を 送ってくるホストを扱う場合である。
- デフォルトでは、 interact は、ユーザーが Expect プロセス自身の標準入力に書き込み、標準出力を見ていると思っている。 -u フラグ("user"のu)は interact に、引数で付けられた名前(spawned id である)のプロセスをユーザーとして 扱う。
- これにより、変なループなしに2つの無関係なプロセスを結合させることが できる。デバッグする時の助けとして、Expect は常に診断結果を stderr へ送る。(ある種のログとデバッグ情報は stdout に送られる)。 同じ理由で、 interpreter コマンドは、stdin からデータを読む。
- 例えば、以下の断片はログインプロセスを作る。そして、(表示されない)
ユーザーにダイアルし、両方の接続を行なう。
もちろん、loginをどんなプロセスに変えても良い。例えば、シェルなら、ア
カウントとパスワードを与えなくてもユーザーが起動できる。
spawn login set login $spawn_id spawn tip modem # dial back out to user # connect user to login interact -u $login複数のプロセスへの出力を行なうため、 -output フラグを前につけた各 spawn id のセットがリストされる。 出力 spawn id の組への入力は、 -input フラグによって決定される。 ( -input と -output フラグは両方とも expect コマンドの -i フラグと同じ書式である。( interact 内の any_spawn_id は意味がない点を除く。) 以下のフラグと文字列(あるいはパターン)は全て、別の -input フラグが現れるまで この入力を適用する。 -input が現れなかった場合、 -output は "-input $user_spawn_id -output" を行なう。 ( -input を持たないパターンも同様である。) -input が一つだけ指示されると、$user_spawn_id はその値で置き換わる。 二つめの -input が指示されると、$spawn_id が置き換わる。 以降の -input フラグも指定できる。2つの入力プロセスはデフォルトで $spawn_id と $user_spawn_id に出力される。 もし、 -input フラグが -output フラグなしで指定された場合、プロセスからの文字は捨てられる。-i フラグは、現在の spawn_id を書き換える。 ただし、 -input または -output フラグが使われていない場合である。-i フラグは -o フラグを含む。間接 spawn id を使って会話しているプロセスを切替えることが可能である。 (間接 spawn id は、expect コマンドの項で説明した) 間接 spawn id は、-i, -u, -input, -output フラグで指定できる。
- interpreter [args]
- は、ユーザーに Expect と Tcl コマンドのためのプロンプトを表示する。 各コマンドの結果が表示される。
- break や continue は制御構造(すなわち、 for proc )で、通常通りに動く。 しかし、 return は、呼出元への復帰を行なうのに対し、 inter_return は interpreter を、呼出元を復帰させる。たとえば、 "proc foo" は、 interpreter を呼び、 inter_return を実行し proc foo が復帰する。 他のコマンドは interpreter に新しいコマンドのためのプロンプトを表示し続ける。
- デフォルトでは、プロンプトは 2 つの整数を含んでいる。 最初の数は評価スタックの深さ(つまり、何回 Tcl_Eval が呼ばれたか) 2番めの数は、Tcl ヒストリ識別番号である。プロンプトは "prompt1"と呼ばれるプロシジャを定義することで設定できる。 このプロシジャの帰り値が次のプロンプトとなる。 記述に開きクオート、括弧、ブレース、ブラケットがあると、次の行には 第 2 プロンプトが現れる(デフォルトは "+> ")。第 2 プロンプトは "prompt2"と呼ばれるプロシジャを定義することで設定できる。
- interpreter の間は、呼出元が raw モードであったとしても、cooked モードが使われる。
- stdin が閉じられると、 interpreter は -eof フラグが使われていない限り復帰する。 使われている場合は引き続く引数を実行する。
- log_file [args] [[-a] file]
- ファイル名が与えられると、
log_file
は、(現時点からの)セッションのログをそのファイルに採取する。
引数がなければ、
log_file
は記録をやめる。使っていたログファイルはクローズされる。
ファイル名の代わりに、Tcl ファイル識別子を指定すると、 -open や -leaveopen フラグが使える。 spawn コマンドと同様だ(より詳しくは、 spawn を参照)-a フラグは、 log_user コマンドによって抑止されたログに出力を強制するものである。デフォルトでは、 log_file コマンドは古い記録を消して書き直したりせずに 追記 する。 ログオフや複数のログを書く時に都合が良いように。 ファイルを消して書き直す時は -noappend フラグを使う。-info フラグは、最後にログした内容を返す(最後が-infoフラグ付きだったら、 その前の内容)。
- log_user -info|0|1
- デフォルトでは、send/expect
ダイアログは標準出力にロギングされる。
(開いていればログファイルにもロギングされる。)
"log_user
0"とすると、標準出力へのロギングが抑止される。
"log_user
1"とすると、復旧する。ログファイルへの記録については
変更はない。
-info フラグは、最後にログした内容を返す(最後が -info フラグ付きだったら、 その前の内容)。
- match_max [-d] [-i spawn_id] [size]
- は、バッファサイズを(バイト単位で)定義する。このバッファは、 expect の内部で使われる。 引数 size がないと、現在のサイズを復帰する。
- -d フラグを指示すると、デフォルトサイズが設定される。(初期状態の デフォルト値は 2000。) -i フラグを指示すると、名前つき spawn id に対してサイズが設定される。 指定しなければ、カレントプロセスに対して設定される。
- overlay [-# spawn_id] [-# spawn_id] [...] program [args]
- は、 program args を現在の Expect プログラム上で実行する。現在の Expect プログラムは終了する。 ただのハイフンが引数に指定されると、コマンド名の前にハイフンをつけて ログインシェルとして扱う。 全てのクローズ中の spawn_id は、引数に使われた文字列を待つ。
- Spawn_id
は、新しいプログラムに継承させるためのファイル
ID に
マップされる。例えば、以下の行はチェスを行ない、chess
master
という現プロセスに制御させる。
overlay -0 $spawn_id -1 $spawn_id -2 $spawn_id chessこれは、 "interact -u" とするよりも効果的である。しかし、 Expect プロセスが制御していないのでプログラム能力が犠牲となる。
- 制御されない端末ができてしまうことに注意すること。それで、 disconnect するか標準入力をリマップするとジョブ制御プログラム (シェル、ログインなど)が正しく機能しない。
- parity [-d] [-i spawn_id] [value]
- は、spawn idの出力からパリティを保持するか取り除くかを設定する。 value が 0 であれば、パリティは取り除かれる。 それ以外の場合、取り除かれない。 value が指定されない場合、現在の値が復帰する。
- -d フラグは、パリティのデフォルト値を設定する。(イニシャル時のデフォルト値は 1 である。すなわち、パリティが取り除かれる。) -i フラグを指示すると、パリティの値が引数の名前つきの spawn id に対して 設定される。引数がなければ現在のプロセスに対して設定される。
- remove_nulls [-d] [-i spawn_id] [value]
- は、前にパターンマッチしたあるいは expect_out か interact_out に保存されている spawn されたプロセスの出力からヌルを保持するか取り除くかを 設定する。 value が 1 なら、ヌルは取り除かれる。もし、 value が 0 なら、ヌルは取り除かれる。 value がなければ、現在の値が復帰する。
- -d
フラグは、デフォルト値を設定する。(イニシャルのデフォルト値は、
1
である。それゆえ、ヌルは取り除かれる。)
-i
フラグは、名前つきの
spawn id
に対して値を設定する。なければ、
現プロセスに対して設定する。
ヌルを取り除くかどうかによらず、 Expect は、ログと標準出力にはヌルが記録される。
- send [-flags] string
- string
を現プロセスに送る。
例えば、以下のコマンド:
send "hello world\r"は、文字 h e l l o <blank> w o r l d <return> を現在のプロセスに 送る。 (Tcl は、printf に似たコマンド ( format と呼ばれる )を持っていて、複雑な文字列を組み立てることができる。)
- 文字は直ちに送られる。ただし、入力にラインバッファのあるプログラムでは、
リターンコードが送られるまで文字が読まれない。リターンコードは、
"\r"と表記する。
-- フラグは、続く引数をフラグと解釈せず文字列として解釈される。 全体としてフラグに見えなくても"--"が前についた文字列はフラグとして 扱われてしまう。このフラグは処理されていない文字列がフラグとして 扱われるのを防ぐ。 ("-"で始まる文字は全て将来のオプションとして予約されている。)-i フラグは、名前つきの spawn_id に文字列を送ることを宣言する。 その spawn_id が user_spawn_id であれば、端末はraw モードに入り、文字列中の改行が復帰改行シーケンスに 変換される。それで、外からは 端末が cooked モードとなっているように 見える。 -raw フラグは、この変換を抑止する。-null フラグは、ヌル文字を送る(0 バイト)。デフォルトでは、ヌル文字を 1つ送る。 -null に続く整数はヌル文字をいくつ送るかを指示する。-break フラグは、ブレーク状態を作る。spawn id が"spawn -open"で指示した tty デバイスを参照する場合のみ意味がある。tip などのプロセスを spawn する場合、tip の都合で ブレーク状態を作るべきである。-s フラグは、出力を強制的に"遅く"する。結果、コンピュータが打ち込んでいる バッファに人間が打ち込んでしまう状況を避けることができる。この出力は 変数"send_slow"の値で制御される。この変数は二つの要素を持つリストである。 最初の要素は、アトミックに送るバイト数である。2 番めの要素はアトミックに送る 間隔(秒)である。例えば、 "set send_slow {10 .001}" は "send -s" に 10 文字送る毎に1ミリ秒待つように指示する。-h フラグは、人間の実際の入力に似せて send を行なう。(アルゴリズムは、 Weibull distribution に基づいていて、この特定のアプリケーション Expect? に 合わせるための修正が行なわれている。) この出力は変数"send_human"の値で制御されていて、この変数は 5 つの要素から なるリストで最初の 2 つの要素は文字間の平均インターバル時間(秒)である。 1 つめがデフォルト値で、2 つめが(通常発生する微妙な待ち時間を表現する) 単語の終りの値である。3 つめの要素は変動率である。 可能な値は 0 から 無限大である。最後の 2 つのパラメタは、それぞれ、 インターバル時間の最小値と最大値である。この 2 つの値は最後に使われて、 最終時刻をクリップする。この 2 値が違うと究極の平均は与えられた平均とは、 全く違ったものになる。例として、続くコマンドが一定の速度で速く打つタイピストを エミュレートする:
set send_human {.1 .3 1 .05 2} send -h "I'm hungry. Let's do lunch."ハングさせてしまった後は、以下のようにした方が良いだろう。:set send_human {.4 .4 .2 .5 100} send -h "Goodd party lash night!"send にエラーや修正を埋め込んであっても、 エラーはシミュレートされない点に注意すること。ブレークを送るためや、ゆっくりした出力を行なったり、人間が出力したように 見せかけるためにヌル文字を送るフラグは相互排他される。 最後に指定されたものだけが使われる。それ以上は、 string の引数が、ヌル文字あるいはブレークを送るフラグとして指定できる。最初の send より前に expect を置いた方が良い。 expect は、プロセスが始まるのを待てるが、 send は待てない。 特に、最初の send は、プロセスが走り始める前に完了する。あなたのデータが無視される 危険がある。 最初にプロンプトを表示しないような対話的なプログラムでは、 次のように send の前にディレイをつけることができる:# どのように破るかのヒントをハッカーに与えてしまわないように、 # このシステムでは外部のパスワードに対するプロンプトを提供しない。 # exec が完了するのを 5 秒待て。 spawn telnet very.secure.gov sleep 5 send password\rexp_send は send のエイリアスである。あなたが Expectk か、Tk 環境で動く Expect の他の変種を 使っている場合、 send は、全く異なった目的のために使われている。 exp_send が、両環境の間での互換性のために提供されている。 似たようなエイリアスが他の Expect の他の send コマンドのために提供されている。
- send_error [-flags] string
- send と似たようなもので、現プロセスでなく stderr に出力される。
- send_log [--] string
- send と似たようなもので、ログファイルだけに string を送る。( log_file を参照。) 引数はログファイルが open されていなければ無視される。
- send_tty [-flags] string
- send と似たようなもので、現プロセスでなく /dev/tty へ出力を送る。
- send_user [-flags] string
- send と似たようなもので、現プロセスでなく標準出力へ出力を送る。
- sleep seconds
- は、与えられた数字の秒数だけスクリプトがスリープする。 seconds は、10進数だけが許される。 (Expectk を使っている場合、Tkのイベントと)割り込みは、Expectが スリープしている間も処理される。
- spawn [args] program [args]
- program args を走らせる新しいプロセスを生成する。その標準入力と標準出力は Expect に結びつけられる。それで、他の Expect コマンドで読んだり書いたりできる。 接続は close によって、あるいは、プロセスそのものがファイル ID の いずれかをクローズした場合、破壊される。
- プロセスは spawn によって始められる。変数 spawn_id には、そのプロセスへの参照を行なう識別子が設定される。 spawn_id によって記述されるプロセスは current process が考慮される。 spawn_id は、読んでも書いても良く、効果的なジョブ制御を提供する。
- user_spawn_id
はユーザーを参照する識別子の入ったグローバル変数である。
例えば、 spawn_id
が、この値に設定された場合、
expect は、 expect_user
のような動きをする。
error_spawn_id は、標準エラー出力を参照する識別子の入ったグローバル変数である。 例えば、 spawn_id が、この値に設定された場合、 send は、 send_error のような動きをする。
- tty_spawn_id は、/dev/tty
を参照する識別子の入ったグローバル変数である。
/dev/tty が存在しない(cron, at,
バッチスクリプトの中)場合、
tty_spawn_id
は定義されない。以下のように確認することができる。:
if {[info vars tty_spawn_id]} { # /dev/tty exists } else { # /dev/tty doesn't exist # probably in cron, batch, or at script }
- spawn UNIX プロセス ID を復帰する。spawn されたプロセスがない場合、0 が 復帰する。変数 spawn_out(slave,name) は pty スレーブデバイスの名前に設定される。
- デフォルトでは、 spawn はコマンド名と引数をエコーする。 -noecho フラグで spawn がこうするのを止められる。
- -console
フラグは、コンソールへの出力を起こし、spawn
されたプロセスへの
リダイレクトされる。この機能は未サポートのシステムがある。
内部的に、 spawn は pty を使い、ユーザーの tty と同じように初期化される。これは、かなり 初期化してしまうので全ての設定が (stty(1)によると) "正常(sane)" になる。 変数 stty_init が定義されていると、stty の引数の形式を解釈できるので、より詳細な設定を 行なえる。例えば、 "set stty_init raw" は、以降 spawn されたプロセスの端末を raw モードで開始する。 -nottycopy は、ユーザーの tty に基づいた初期化を飛ばす。 -nottyinit は、"正常な"初期化を飛ばす。
- 普通、 spawn
は、実行するのにわずかの時間しかかからない。spawn
に時間をかけたいので
あれば、おそらく割り込まれた
pty
に遭遇するだろう。たくさんのテストが
間違ったプロセスに掛かり合うことを避けることができる。
(割り込まれた pty
につき、10
秒かかる。) -d
オプションをつけて
Expect を走らせると、
Expect
がおかしな状態のたくさんの
pty
に遭遇しているかどうかが表示される。
これらの pty
がつながっているためにプロセスを殺せない場合、リブートするしか
頼れる復旧手段はない。
exec(2)が失敗して program が spawn に成功しなかった場合 (例えば、 program がなかった場合など)、エラーメッセージが次の interact か expect コマンドで復帰する。つまり。 program が、出力としてエラーメッセージを出しているように見せる。 この動作は、 spawn の実装の自然な帰結である。内部で、spawn がフォークされ、その後、 spawn されたプロセスがオリジナルの Expect プロセスとその spawn_id で会話を行なう。-open フラグは、次の引数を Tcl ファイル識別子として解釈する(つまり、 open を行なって復帰する。 ) spawn id は、spawn された id として使われる。(ファイル識別子は、 もう使うべきではない。) これにより、 pty を除く、raw デバイス、ファイル、パイプラインを使うことができる。 0 が返ってくるのは、関連するプロセスがなかった時である。 spawn されたプロセスへの接続がクローズされると、Tcl ファイル識別子も クローズされる。 -leaveopen フラグは、 -open と似た動きをするが、 spawn id をクローズした後もファイル識別子を開いたままにする点が違う。-pty フラグは、 pty をオープンするがプロセスをspawnしない。0 が復帰するのは、 関連するプロセスがない場合である。spawn_id は、通常通り設定される。変数 spawn_out(slave,fd) には、pty スレーブとつながっているファイル識別子が設定される。 "close -slave" で close できる。-ignore フラグは、spawn されたプロセス中で無視されるシグナルの名前を指示する。 なければ、シグナルはデフォルトの振舞いをする。シグナルの名前は trap コマンドで使う名前と同じである。各シグナルを分離するのにフラグが 必要な点を除いては。
- strace level
- は、以降の命令を実行する前に表示を行なう。
(Tcl の trace
は、変数のトレースを行なう。)
level
は、トレースへの呼び出しスタックの深さを示す。
例えば、
以下のコマンドは
Expect 最初の 4
レベルの呼び出しをトレースする。
それ以上の深さはトレースしない。
expect -c "strace 4" script.exp-info フラグを指定すると、strace は最後の info でない指定の内容を復帰する。
- stty args
- は端末モードを変更する。外部の
stty
コマンドと似たようなものである。
デフォルトでは、制御している端末がアクセスされる。他の端末は、 "< /dev/tty..." を追加することでアクセスできる。(引数を一つの引数に まとめるべきではない。)ステータス要求はコマンドの結果としてステータスを復帰する。 ステータスが要求されずに制御している端末にアクセスする場合、直前の raw と echo の状態を返す。例えば、引数 raw か -cooked は、端末を raw モードに設定する。 引数 -raw か cooked は、端末を cooked モードに設定する。 引数 echo か -echo は、端末をそれぞれ echo あるいは noecho モードに設定する。
- 以下の例は、一時的なエコー禁止をどうやっておこなうかを示す。
これは、他の自動スクリプトで、その中にパスワードが埋め込まれるのを
防ぐことに使われる。(もっと議論したければ、下の
EXPECT ヒントに ある。)
stty -echo send_user "Password: " expect_user -re "(.*)\n" set password $expect_out(1,string) stty echo
- system args
- は、 args を、sh(1)に入力する。端末からコマンドを叩くのとちょうど同じである。 Expect は、シェルが終るのを待つ。sh からの復帰値は、 exec がその復帰値を扱うのと同じに扱われる。
- exec が、スクリプトに標準入出力をリダイレクトするのと対照的に、 対照的に system は、リダイレクションを行なわない。(他に文字列そのものでリダイレクトを 指示しない限り。) それで、/dev/tty と直接話さなければならないプログラムを 使うことができる。同じ理由で、 system の結果は、ログに記録されない。
- timestamp [args]
- は、タイムスタンプを復帰する。
引数がない場合、復帰するまでの秒数が返る。
-format フラグは、文字列が続くが、その文字列に POSIX の strftime のルールに従って置換がかかる。 例えば、 %a は曜日(すなわち、Sat)とか。他は以下の通りである。:
%a 略記された曜日の名前 %A 略されない曜日の名前 %b 略記された月の名前 %B 略されない月の名前 %c 次の形式で書かれた時刻: Wed Oct 6 11:45:56 1993 %d 日 (01-31) %H 時 (00-23) %I 時 (01-12) %j 日 (001-366) %m 月 (01-12) %M 分 (00-59) %p am または pm %S 秒 (00-61) %u 日 (1-7, 月曜日が週の最初の日) %U 週 (00-53, 最初の日曜日が第1週の最初の日) %V 週 (01-53, ISO 8601 スタイル) %w 日 (0-6) %W 週 (00-53, 最初の月曜日が第1週の最初の日) %x date-time as in: Wed Oct 6 1993 %X time as in: 23:59:59 %y year (00-99) %Y year as in: 1993 %Z timezone (or nothing if not determinable) %% a bare percent signこの他の % 指定は定義されていない。他の文字は変更されない。 C ロカールだけがサポートされる。-seconds フラグは、 タイムスタンプを秒で表す。-gmt GMT タイムゾーンで出力する。デフォルトはローカルタイムゾーンである。
- trap [[command] signals]
- を実行すると、以降指定された
signal
を受けとると指定された
command を実行する。
このコマンドは、グローバルスコープで実行される。
もし、 command
が指定されなければ、シグナルアクションが復帰する。
command が、文字列 SIG_IGN
であれば、シグナルが無視される。
command が、文字列 SIG_DFL
であれば、シグナルはデフォルトの動きをする。
signals
は、シグナルが1つでも複数のシグナルのリストでも良い。シグナルは、
数字とsignal(3)に記述されている文字列のどちらで指定しても良い。
プレフィクスの"SIG"は、省略しても良い。
引数がなければ(または、引数 -number であれば)、 trap は、trapコマンドで横取りされているシグナル番号を復帰する。-code フラグはコマンドコードを返す。Tcl がコマンドを動かし始めた時に 帰そうとしたコードである。-interp フラグは、trap が宣言された時でなくコマンドが開始された時にインタプリタに コマンドを評価させる。-name フラグは、 trap コマンドに trap のかかっているシグナル名を帰す。-max フラグは、 trap コマンドに設定できる最も大きなシグナル番号を帰す。例えば、"trap {send_user "Ouch!"} SIGINT" は、 ユーザーが ^C を押す度に "Ouch!" を表示する。デフォルトでは、SIGINT(通常 ^C を押すと発生する)や SIGTERM は、Expect を exit させてしまう。これは、Expect が起動時に 実行する以下の trap によって起こっている。
trap exit {SIGINT SIGTERM}-Dフラグを使ってデバッガを起動するなら、SIGINT が再定義されてから対話型 デバッガが起動される。これは以下の trap によって起こる。trap {exp_debug 1} SIGINTデバッガのトラップは、環境変数 EXPECT_DEBUG_INIT を設定して、新しく trap を起動することで変更できる。もちろん、スクリプトにtrapコマンドを足すだけで例のトラップは両方とも 上書きできる。特に、自作の "trap exit SIGINT" があるなら、これは デバッガのトラップを上書きしてしまう。ユーザーにデバッガを全く 触らせないようにするのに、便利である。SIGINT のトラップを独自に定義したいけれど、デバッガにも同時に割り込んで もらいたいのであれば、こう書く。:if ![exp_debug] {trap mystuff SIGINT}代わりに、別のシグナルを使ってデバッガに割り込みをかけることができる。trap は、SIGALRM のアクションを上書きしない。 Expect が内部で使用しない。 disconnect コマンドは、SIGALRMを SIG_IGN (ignore)に設定する。 後から発行される spawn コマンドを実行している間、SIGALRM は ディスエーブル中であれば再度イネーブルにできる。もっと情報が欲しい場合、signal(3) を参照すること。
- wait [args]
- は、spawn されたプロセス(あるいは、名前つきのプロセスがなければ現在のプロセス) が終了するのを待つ。
- wait は、通常 4
つの整数のリストを帰す。
最初の整数は、終了を待ち構えているプロセスの
pid である。 2
つめの整数は、関連する
spawn id である。 3
つめの整数は、オペレーティングシステムエラーがあれば
-1、
そうでなければ、0
である。 3
つめの整数が 0
であれば、4
つめの整数はspawnされたプロセスからのリターン
コードである。3
つめの整数が -1
であれば、4
つめの整数はオペレーティングシステム
によって設定された
errno
の値である。グローバル変数
errorCode も設定される。
追加の要素が wait の復帰値に加わっても構わない。オプションの5つめの要素は、情報クラスの 識別子である。今のところ、この要素の唯一可能な値は CHILDKILLED で、 その場合、次の二つの値が C スタイルのシグナル名と短い文書による記述である。
- -i
フラグによって、wait
を行なう名前付き
spawn_id(プロセス ID
ではなく)を
指定する。SIGCHLD
ハンドラの内部では、spawn
ID -1
を指定することで、
spawn
されたプロセスのいずれかを
wait できる。
-nowait フラグを指定すると、wait が成功の復帰値で即時復帰する。 (あとで)そのプロセスが exit すると、自動的に後始末が行なわれ、明示的に wait する必要がない。wait コマンドは、引数に "-i -1" を指定することによって、 fork したプロセスを待つためにも使われる。 spawn したプロセスに用いられる場合と異なり、 このコマンドはいつでも実行できる。 どのプロセスを待つかを制御することは出来ないが、 返り値はプロセス ID としてチェックできる。
ライブラリ¶
Expect は、スクリプトのための二つのビルトインライブラリを自動的に理解する。 それらは変数 exp_library と変数 exp_exec_library に設定されたディレクトリ名と して定義される。これらのディレクトリには、他のスクリプトによって使える ユーティリティファイルが入っている。整形印刷¶
Expect スクリプトをきれいに印刷するための vgrind の定義がある。 Expect ディストリビューションと一緒に配布されている vgrind 定義が正しく インストールされていると仮定して、こうすれば使える。
vgrind -lexpect file
例¶
マニュアルページによる記述では、あらゆるものをどう組み合わせるのかと いうことが明白ではない。私としては、 Expect ディストリビューションの example ディレクトリにある例を読んで試してみて欲しいと思う。 いくつかは本物のプログラムである。それ以外は特定のテクニックの単純な解説、 あと、もちろん、単なるクイックハックが少しある。 INSTALL ファイルにはこれらのプログラムの簡単な梗概が書かれている。 Expect の論文も役に立つ(関連項目参照)。いくつかは、初期バージョンの Expect の 文法を使っているが、それとともにある根本的な考えは、なお有効であり、 このマニュアルページより詳細に書かれている。警告¶
拡張は Expect のコマンド名と衝突するかもしれない。例えば、 send は、Tk では全く別の目的で定義されている。 そういう理由で、ほとんどの Expect コマンドは、"exp_XXXX" という 別の記法(エイリアス)もサポートする。 "exp", "inter", "spawn", "timeout" で始まるコマンドと変数は、 エイリアスを持たない。 この環境間の互換性が必要であれば、拡張されたコマンド名を用いること。バグ¶
プログラムに "sex" ("Smart EXec" か "Send-EXpect" の略) という名前を つけるのは実に魅力的だったのだが、センスの良い方(あるいは、 単にピューリタニズム)が優先された。
set env(TERM) vt100
set env(SHELL) /bin/sh
set env(HOME) /usr/local/bin
spawn date
sleep 20
expect
のような Expect
プログラムは失敗する。失敗しないように非対話的なプログラムでは
spawn せずに exec
すること。こういう状況は考えられるが、実際には私はまだその状態に
陥ったことがない。つまり、この原因で対話プログラムの最後の出力を
取りこぼすという状態になったことがない。
send "speed 9600\r";
sleep 1
expect {
timeout {send "\r"; exp_continue}
$prompt
}
EXPECT ヒント¶
Expect について、直観的でない点が少しある。 このセクションではそういったことの指摘とそれに対する示唆を試みる。
set prompt "(%|#|\\$) $" ;# default prompt
catch {set prompt $env(EXPECT_PROMPT)}
expect -re $prompt
私としては、見えると思っているものの終りの部分を含んだ
expect
パターンを書くように勧める。そうすれば、全体を見る前に応答を返してしまう
ことを避けることができる。さらに、全体が見える前に答えることもできるが
その文字は質問に混ざって
echo
される。言い替えれば、会話は正常だが見た目は
混ざって見える。
2751 (-rwxr-s--x) で、同じグループの所有で作成する。 こうすると、シェルスクリプトはだれからも実行でき(かつ、読め)る。 実行すると、それは Expect スクリプトを実行する。
関連項目¶
Tcl(3), libexpect(3)著者¶
Don Libes, National Institute of Standards and Technology謝辞¶
Tclを生み出した John Ousterhout と、インスピレーションを与えてくれた Scott Paisley に感謝する。 Expect のオートコンフィギュレーションコードについて、 Rob Savoye に感謝する。| 29 December 1994 |