説明を使用して

1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...

Linuxの使用の詳細な説明は期待しています

I.概要

Shellを使ってループ、判定などの簡単な制御フロー関数を実装することができます。 ただし、対話が必要な状況では、手動で介入する必要があります。対話型のプログラム、たとえばTelnetサーバーとの対話を実装する必要が生じることがあります。 Expectは、この機能を実装するためのツールです。

Expectは、人間の介入なしに自動的かつ対話的な作業を可能にする無料のプログラミング言語です。 Expectの著者Don Libesは、1990年にExpectを書くようになりました.Expectの定義は、次のとおりです。Expectは、対話型ツールを自動化するためのソフトウェアスイートです。 システム管理者は、これを使用して、ターミナルからの入力を受け取ることを期待するコマンドまたはプログラムへの入力を提供するために使用できるスクリプトを作成することができます。 Expectは、プログラムによって提供される標準入力をシミュレートして、対話的なプログラム実行を実装するためにプログラムが必要とする入力を提供することができる。 簡単なBBSチャットボットを実装することも可能です。 🙂

期待は常に進化しています。時間の経過とともに、その機能はより強力になり、システム管理者にとって強力な助手になっています。 ExpectにはTclプログラミング言語のサポートが必要です。システムでExpectを実行するには、まずTclをインストールする必要があります。

第二に、期待する働き原則

最も簡単なレベルでは、Expectは一般的なチャットスクリプトツールのように機能します。 チャットスクリプトは、もともとUUCPネットワークで使用され、コンピュータが接続を確立する必要があるときに特定のログインセッションを自動化しました。

チャットスクリプトは、一連のexpect-sendペアで構成されています。特定のレスポンスを送信する前に、特定の文字の出力を待ちます。 たとえば、次のチャットスクリプトの実装では、Login:文字列で標準出力が表示されるのを待ってから、誰かをユーザー名として送信してから、Password:プロンプトを待ち、sillymeに応答します。

引用:ログイン:somebodyパスワード:sillyme

このスクリプトは、ログインプロセスを実装し、特定のユーザ名とパスワードでログインするために使用されます。

Expectの最も単純なスクリプト操作モードは、基本的にChatスクリプトモードと同じです。

例:

1、機能を達成するために

以下では、chshコマンドに応答するスクリプトを分析します。 最初にこの対話型コマンドの形式を見てみましょう。 ユーザーchavezのログインスクリプトを変更したいとします。コマンドの対話プロセスは次のとおりです。

引用:#chsh chavez

chavezのログインシェルの変更

新しい値を入力するか、デフォルトの場合はreturnキーを押します

ログインシェル[/ bin / bash]:/ bin / tcsh

このコマンドは、最初に数行のプロンプト情報を出力し、ユーザーの新しいログインシェルを入力するように指示することがわかります。 プロンプトメッセージの後にユーザーのログインシェルを入力するか、ログインシェルを変更せずに直接Enterキーを押す必要があります。

次は、このコマンドの実行を自動化するために使用できるExpectスクリプトです。

#!/ usr / bin / expect

#ログインシェルをtcshに変更する

ユーザーを設定する[lindex $ argv 0]

chsh $ userを生成する

Expect "]:"

"/ bin / tcsh"を送信する

期待する

出口

この簡単なスクリプトは、多くのExpectプログラムの機能を説明することができます。 他のスクリプトと同様に、最初の行はスクリプトの実行に使用されるコマンドプログラムを指定します。ここに/ usr / bin / expectがあります。 プログラムの最初の行は、スクリプトの実行パラメータ(配列$ argvに格納され、0から始まりパラメータです)を取得し、変数userに保存されます。

2番目のパラメータはExpectのspawnコマンドを使用してスクリプトとコマンドセッションを開始します。ここではchshコマンドが開始されていますが、コマンドは派生した子プロセスとして実行されます。

後続のexpectコマンドとsendコマンドは、対話プロセスを実装するために使用されます。 chshが出力する文字列が出力に表示されたら(通常、文字列は入力を待っている最後のプロンプトの特性情報であることが多い)、まず、出力に[]:文字列が現れるのを待ちます。 他の不一致情報については、完全に無視されます。 スクリプトが文字列を受け取ると、expectは/ bin / tcshとキャリッジリターンをchshコマンドに送ります。 最後に、スクリプトはコマンドが終了するのを待ちます(chshが終了します)。子プロセスを特定したeofキャラクタが受信されると、expectスクリプトが終了します。

3、応答する方法を決定する

管理者は、現在の状況に応じて異なる方法でコマンドに応答する必要があることがよくあります。 以下の例から、期待は非常に複雑な条件付き応答を達成できることがわかります。プレスクリプトを変更することで簡単に達成できます。 次の例は、より複雑なexpect-sendの例です。

Expect -re "\ [(。*)]:"

{$ expect_out(1、string)!= "/ bin / tcsh"} {

送信 "/ bin / tcsh"}

送信 "

期待する

この例では、最初のexpectコマンドは-reパラメータを使用します。これは、指定された文字列が通常の文字列ではなく正規表現であることを示します。 上記の例では、左括弧文字(3回エスケープする必要があります。したがって、3つのシンボルがあります。これは、expectと正規表現の特殊文字であるためです)に続けてゼロ以上文字、そして最後に右括弧文字。 。*は、1つ以上の任意の文字を表すことを意味し、()に格納されます。これは、一致した結果に後でアクセスするために、一致の結果が変数に格納されるためです。

一致するものが見つかったら、[]に含まれる文字列を調べて、それが/ bin / tcshであるかどうかを確認します。 そうでない場合は、/ bin / tcshをchshコマンドの入力として送信し、そうであれば1つのキャリッジリターンのみを送信します。 特定の状況に対応するこのシンプルで小規模の例は、期待されるパワーを示しています。

正規表現では、()にいくつかの部分を入れ、expect_out配列を通してそれらにアクセスすることができます。 各パートは、式の左から右に1から始まり(0は一致する出力全体を含む)コード化されます。 ()を入れ子にすることができます。この場合、エンコーディングは最内層から最外層まで行われます。

4、タイムアウトを使用する

次に期待される例は、タイムアウト機能を持つプロンプト機能を示しています。 このスクリプトはユーザーに入力を促し、一定時間入力がない場合はタイムアウトしてデフォルトの応答を返します。 このスクリプトは、プロンプト文字列、デフォルトの応答、タイムアウト(秒)の3つのパラメータを受け取ります。

#!/ usr / bin / expect

#タイムアウトとデフォルトのプロンプト機能。

プロンプトを設定する[lindex $ argv 0]

defを設定する[lindex $ argv 1]

応答を設定する$ def

toutを設定する[lindex $ argv 2]

スクリプトの最初の部分は、実行中のパラメータを最初に取得し、内部変数に保存します。

Send_tty "$ prompt:"

タイムアウト$を設定する

期待 "" {

生の$ expect_out(バッファ)を設定する

#最終的な復帰を取り除く

レスポンスを設定する[string trimright "$ raw"] "]

}

{"$ response" == "} {レスポンス$ defを設定}

"$応答を送る

これはスクリプトの残りの部分です。 send_ttyコマンドを使用して、プロンプト文字列とコロンとスペースを端末に表示することがわかります。 set timeoutコマンドは、すべての後続のexpectコマンドの待機応答のタイムアウトを$ toutに設定します(-lパラメータはタイムアウト設定を無効にするために使用されます)。

次に、expectコマンドは出力にキャリッジリターン文字を待ちます。 タイムアウトの前にキャリッジリターンが得られた場合、setコマンドはユーザー入力の内容をrawにフェースチェンジします。 後続のコマンドは、ユーザー入力から最後のキャリッジリターンシンボルを削除し、それを変数responseに割り当てます。

応答が空の場合、応答値はデフォルトに設定されます(ユーザーがタイムアウト後に入力しなかった場合、またはユーザーがキャリッジリターンを入力した直後の場合)。 最後のsendコマンドは、レスポンス変数の値とキャリッジリターンを標準出力に送信します。

1つの興味深いことは、スクリプトがspawnコマンドを使用しないことです。 expectスクリプトは、スクリプトを呼び出すプロセスと対話します。

スクリプトがプロンプトと呼ばれる場合は、Cスタイルのシェルで使用できます。

%set a = 'プロンプト'答えを入力する "silence 10 '

答えを入力してください:テスト

%echoは "$ a"でした

答えはテストだった

プロンプトで設定されたタイムアウトは10秒です。 タイムアウトまたはユーザがキャリッジリターンシンボルを入力した直後であれば、echoコマンドが出力します

答えは "沈黙"

5.より複雑な例

以下では、より複雑な制御構造と複雑な相互作用を使用するexpectスクリプトのより複雑な例について説明します。 この例は、任意のユーザーに書き込みコマンドを送信するために使用されます。送信されたメッセージは、ファイルまたはキーボード入力から送信されます。

#!/ usr / bin / expect

#準備されたファイルから複数のユーザに書き込む

#または対話的なメッセージ入力

{$ argc <2} {

Send_user "使用法:$ argv0ファイルuser1 user2 …"

出口

}

send_userコマンドは、親プロセス(通常はユーザーのシェル)にヘルプ情報を使用して標準出力を表示するために使用されます。

nofileを0に設定する

#Tclのlindex関数でファイル名を取得する

ファイルを設定する[lindex $ argv 0]

{$ file == "i"} {

nofile 1を設定する

}その他{

#メッセージファイルが存在することを確認する

{[file isfile $ file]!= 1} {

Send_user "$ argv0:ファイル$ファイルが見つかりません。"

終了}}

このセクションでは、処理スクリプト起動パラメータを実装します。送信パラメータは、送信するメッセージを格納するファイル名または対話型入力を使用して送信されたコンテンツを表す「i」コマンドのいずれかでなければなりません。

変数ファイルは、スクリプトの最初の引数の値に設定されます。これはTcl関数lindexによって実装され、リスト/配列から特定の要素を取得します。 []は、lindexの戻り値をsetコマンドのパラメータとして実装するために使用されます。

スクリプトの最初のパラメータが小文字の "i"の場合、変数nofileは1に設定されます。そうでない場合、引数で指定されたファイルはTclのisfile関数を呼び出して検証され、存在しない場合はエラーが終了します。

ifコマンドが論理判定機能を実装するために使用されていることがわかります。 このコマンドの直後には判定条件が続き、判定条件実行後の{}内のコマンドが実行されます。 if条件がfalseの場合、elseの後のブロックが実行されます。

procs {}を設定する

#書き込みプロセスを開始する

{set i 1} {$ i <$ argc}

{incr i} {

スポーン – ノーコーライト

[lindex $ argv $ i]

procs $ spawn_idをラップする

}

最後の部分では、spawnコマンドを使用して書き込みプロセスを開始し、ユーザーにメッセージを送信します。 ここではforコマンドを使用してループ制御関数を実装しています。ループ変数は最初に1に設定されてからインクリメントされます。 ループ本体は最後の{}の内容です。 ここでは、スクリプトの2番目とそれ以降の引数でwriteコマンドを生成し、各引数をメッセージ送信用のユーザー名として使用します。 lappendコマンドは、各生成プロセスのプロセスID番号を保持する内部変数$ spawn_idを使用して、変数procs内のプロセスID番号のリストを作成します。

{$ nofile == 0} {

Setmesg [open "$ file" "r"]

}その他{

Send_user "メッセージを入力し、

^ Dで終わる: "}

最後のスクリプトは、メッセージファイルを開くか、変数nofileの値に基づいてメッセージを送信するようにユーザーに求めます。

タイムアウト-1を設定

1 {

{$ nofile == 0} {

もし、{[$ mesg chars] == -1}ブレーク

行 "$ chars"を設定する

}その他{

Expect_user {

-re "" {}

Eofブレーク}

行$ expect_out(バッファ)を設定}

Foreach spawn_id $ procs {

Send $ line}

スリープ1}

出口

上記のコードは、実際のメッセージテキストが無限ループを通してどのように送信されるかを示しています。 whileループのifループは、メッセージの取得方法を決定します。 非対話モードでは、次の行はメッセージファイルから読み込まれ、whileループはファイルの内容が終了すると終了します。 (breakコマンドは終了ループを実装します)。

対話型モードでは、expect_userコマンドはユーザーからメッセージを受け取ります。ユーザーがctrl + Dを入力すると、入力が終了してループが終了します。 どちらの場合でも、変数$ lineは、次の行のメッセージコンテンツを保存するために使用されます。 メッセージファイルの場合、メッセージ末尾に改行が付加されます。

foreachループは、生成されたすべてのプロセスを反復処理します。これらのプロセスのID番号は、$ procsリスト変数に格納され、各プロセスと個別に通信します。 sendコマンドは、foreachのループ本体を構成し、現在の書き込みプロセスにメッセージを送信します。 whileループはsleepコマンドで終了します。これは主に、非対話モードを処理するために使用され、メッセージが各書き込みプロセスにあまりにも速く送られないようにします。 whileループが終了すると、expectスクリプトは終了します。

その他の情報:

Linuxでのスクリプト作成のための柔軟なヒント


1 Star2 Stars3 Stars4 Stars5 Stars (まだ評価されていません)
Loading...
      この投稿は審査処理中  | 元のサイトへ