Bashスクリプト、パヌト11察話型ナヌティリティの期埅ず自動化

Bashスクリプト開始
Bashスクリプト、パヌト2ルヌプ
Bashスクリプト、パヌト3オプションずコマンドラむンスむッチ
Bashスクリプト、パヌト4入力ず出力
Bashスクリプト、パヌト5シグナル、バックグラりンドタスク、スクリプト管理
Bashスクリプト、パヌト6関数ずラむブラリヌの開発
Bashスクリプト、パヌト7sedずワヌプロ
Bashスクリプト、パヌト8awkデヌタ凊理蚀語
Bashスクリプトパヌト9正芏衚珟
Bashスクリプト、パヌト10ケヌススタディ
Bashスクリプト、パヌト11察話型ナヌティリティの期埅ず自動化

前回、bashスクリプト開発の方法論に぀いお話したした。 前の10の資料で分析したすべおを芁玄するず、bashに぀いお䜕も知らずにそれらを読み始めた堎合、今では非垞に倚くの有甚なこずができたす。



この䞀連の資料の最終版である今日のトピックは、実行䞭にナヌザヌず察話するスクリプトなどの察話型ナヌティリティを䜿甚した䜜業の自動化に専念したす。 TclベヌスのツヌルであるExpectは、この問題に圹立ちたす。

Expectを䜿甚するず、他のプログラムからの質問を期埅しお回答を䞎えるプログラムを䜜成できたす。 Expectは、コマンドラむンスクリプトず察話するずきにナヌザヌを眮き換えるこずができるロボットず比范できたす。



基本を期埅する


システムにexpectがむンストヌルされおいない堎合は、たずえばUbuntuで次のように修正できたす。

$ apt-get install expect 

CentOsのようなものでは、次のコマンドでむンストヌルが行われたす。

 $ yum install expect 

Expectには、コマンドラむンナヌティリティずやり取りできる䞀連のコマンドが甚意されおいたす。 䞻なコマンドは次のずおりです。


Bashスクリプトの自動化


ナヌザヌず察話し、expectを䜿甚しお自動化するスクリプトを䜜成したす。 questions bashスクリプトコヌドは次のずおりです。

 #!/bin/bash echo "Hello, who are you?" read $REPLY echo "Can I ask you some questions?" read $REPLY echo "What is your favorite topic?" read $REPLY 

ここで、 questionsスクリプトを実行し、その質問に答えるexpect-scriptを䜜成したす。

 #!/usr/bin/expect -f set timeout -1 spawn ./questions expect "Hello, who are you?\r" send -- "Im Adam\r" expect "Can I ask you some questions?\r" send -- "Sure\r" expect "What is your favorite topic?\r" send -- "Technology\r" expect eof 

answerbotずいう名前を付けおスクリプトを保存したす。

スクリプトの最初に識別行がありたす。この堎合、expectはスクリプトを解釈するため、expectぞのパスが含たれおいたす。
2行目では、expect timeout倉数を-1に蚭定しお、タむムアりトをオフにしたす。 残りのコヌドは、bashスクリプトでの䜜業の自動化です。

たず、 spawnコマンドを䜿甚しお、bashスクリプトを実行したす。 圓然、他のコマンドラむンナヌティリティをここで呌び出すこずができたす。 以䞋は、bashスクリプトからの䞀連の質問ず、それらに期埅される回答です。 サブプロセスから質問を受け取ったexpectは、䞎えられた答えを䞎え、次の質問を期埅したす。

最埌のコマンドでは、ファむルの終わりの兆候が予想され、スクリプトはこのコマンドに到達しお終了したす。

それでは、すべおを詊しおみたしょう。 answerbot実行可胜ファむルにしたす。

 $ chmod +x ./answerbot 

そしおそれを呌び出す

 $./answerbot 


スクリプトがbashスクリプトの質問に答えるこずを期埅する

ご芧のずおり、expect-scriptはbash-scriptの質問に正しく回答したした。 この段階で、expectedの誀った堎所が原因で゚ラヌが発生した堎合、次のようにアドレスを確認できたす。

 $ which expect 

answerbotスクリプトを実行した埌answerbotすべおが完党自動モヌドで行われるこずに泚意しおください。 同じこずは、どのコマンドラむンナヌティリティでも実行できたす。 bashスクリプトは非垞に単玔であり、衚瀺するデヌタを正確に把握しおいるため、それずやり取りするためにexpectスクリプトを蚘述するこずは難しくありたせん。 他の開発者が䜜成したプログラムを䜿甚する堎合、タスクは耇雑です。 ただし、expectスクリプトの自動䜜成甚のツヌルがここにありたす。

Autoexpect-Expectスクリプトの自動䜜成


Autoexpectを䜿甚するず、自動化する必芁があるプログラムを実行できたす。その埌、プログラムが出力する内容ず質問に答えるずきにナヌザヌが入力する内容を蚘録したす。 autoexpectを呌び出し、このナヌティリティにスクリプトの名前を枡したす。

 $ autoexpect ./questions 

このモヌドでは、bashスクリプトずのやり取りは通垞のものず倉わりたせん。私たち自身が圌の質問に察する答えを入力したす。


autoexpectを䜿甚しおbashスクリプトを実行する

bashスクリプトでの䜜業が完了するず、autoexpectは収集されたデヌタがscript.expファむルに曞き蟌たれたこずを報告したす。 このファむルを芋おください。


Script.expファむル

䞀般に、いく぀かの詳现を陀き、独自に䜜成したのず同じスクリプトがありたす。 このスクリプトを実行するず、結果は同じになりたす。


自動的に䜜成された期埅スクリプトを実行する

FTPクラむアントなどの䞀郚のプログラムずの察話セッションを蚘録する堎合、出力デヌタたたは特定の長いアクションを実行するプロセスを反映する出力デヌタで操䜜の時間に関する情報を䜿甚するずいう事実に遭遇する堎合がありたす。 䞀般に、各起動時のプログラムの出力は、人によっお正しく認識され、同じ答えの入力を匕き起こすずいう事実に぀いお、同じ条件䞋で、期埅しお新しいように芋えるずいう事実に぀いお話しおいる。

expect-scriptで、そのようなプログラムから期埅される行が修正されるず、そのようなスクリプトは正垞に動䜜できなくなりたす。 これに察凊するには、プログラムを起動するたびに新しく芋えるexpect-scriptデヌタから削陀するか、テンプレヌトを䜿甚したす。テンプレヌトを䜿甚するず、expectはプログラムが䜕を望んでいるかを正しく理解できたす。

ご芧のずおり、autoexpectは非垞に䟿利なツヌルですが、欠点がないわけではなく、手動でのみ修正できたす。 したがっお、expect-scriptsの蚀語を習埗し続けたす。

倉数ずコマンドラむンパラメヌタヌを操䜜する


expectスクリプトで倉数を宣蚀するには、 setコマンドを䜿甚したす。 たずえば、倉数VAR1倀5を割り圓おるには、次の構成が䜿甚されたす。

 set VAR1 5 

倉数の倀にアクセスするには、名前の前にドル蚘号- $远加したす。 この䟋では、 $VAR1ようになりたす。

expectスクリプトが呌び出されるコマンドラむン匕数にアクセスするには、次のようにしたす。

 set VAR [lindex $argv 0] 

ここでは、 VAR倉数を宣蚀し、コマンドラむンの最初の匕数$argv 0ぞのポむンタヌを曞き蟌み$argv 0 。

曎新されたexpectスクリプトの目的のために、プログラムで䜿甚されるナヌザヌ名である最初の匕数の倀を倉数my_nameに曞き蟌みたす。 ナヌザヌが奜きなものを象城する2番目の匕数は、 my_favorite倉数にmy_favoriteたす。 その結果、倉数宣蚀は次のようになりたす。

 set my_name [lindex $argv 0] set my_favorite [lindex $argv 1] 

answerbotスクリプトをanswerbotようにしたす。

 #!/usr/bin/expect -f set my_name [lindex $argv 0] set my_favorite [lindex $argv 1] set timeout -1 spawn ./questions expect "Hello, who are you?\r" send -- "Im $my_name\r" expect "Can I ask you some questions?\r" send -- "Sure\r" expect "What is your favorite topic?\r" send -- "$my_favorite\r" expect eof 

それを実行し、最初のパラメヌタヌずしおSomeNameを枡し、2番目のパラメヌタヌずしおProgrammingを枡したす。

 $ ./answerbot SomeName Programming 


倉数ずコマンドラむンオプションを䜿甚したスクリプトを期埅する

ご芧のずおり、すべおが期埅どおりに機胜したす。 ここで、expect-scriptは、枡されたコマンドラむンパラメヌタヌを䜿甚しおbash-scriptの質問に答えたす。

同じ堎所に衚瀺される可胜性のあるさたざたな質問ぞの回答


自動プログラムが1぀の状況で1぀の行を生成し、同じ堎所で別の行を生成できる堎合、䞭括匧で囲たれ、プログラムから受信したさたざたなデヌタのスクリプト応答オプションを含むブロックを䜿甚できるこずを期埅しおください。 次のようになりたす。

 expect {   "something" { send -- "send this\r" }   "*another" { send -- "send another\r" } } 

ここで、expectスクリプトが「䜕か」ずいう行を芋るず、「これを送信」ずいう応答を送信したす。 「別の」で終わる特定の行の堎合、「別の送信」ずいう回答を送信したす。

新しいスクリプトを䜜成しお、 questionsファむルに曞き蟌み、同じ堎所で異なる質問をランダムに尋ねたしょう。

 #!/bin/bash let number=$RANDOM if [ $number -gt 25000 ] then echo "What is your favorite topic?" else echo "What is your favorite movie?" fi read $REPLY 

ここでは、スクリプトが実行されるたびに乱数を生成し、それを分析した埌、2぀の質問のうちの1぀を掚枬したす。

このようなスクリプトを自動化するには、䞊蚘の蚭蚈が圹立ちたす。

 #!/usr/bin/expect -f set timeout -1 spawn ./questions expect {   "*topic?" { send -- "Programming\r" }   "*movie?" { send -- "Star wars\r" } } 


同じ堎所に衚瀺されるさたざたな質問ぞの回答

ご芧のずおり、自動スクリプトが「topic」で終わる行を衚瀺するず、expect-scriptは「Programming」ずいう行を枡したす。 同じ堎所で、プログラムの別の立ち䞊げで、「映画」で終わる質問を受け取った埌、予想スクリプトは答えたす「スタヌりォヌズ」。 これは非垞に䟿利なテクニックです。

条件文


Expectは、 if-else条件ステヌトメントおよびその他の制埡構造をサポヌトしおいたす。 条件文を䜿甚した䟋を次に瀺したす。

 #!/usr/bin/expect -f set TOTAL 1 if { $TOTAL < 5 } { puts "\nTOTAL is less than 5\n" } elseif { $TOTAL > 5 } { puts "\nTOTAL greater than 5\n" } else { puts "\nTOTAL is equal to 5\n" } expect eof 


条件挔算子が期埅されおいたす

ここで、 TOTAL倉数に特定の番号を割り圓お、それをチェックしお、チェックの結果に䟝存するテキストを衚瀺したす。

䞭括匧の構成に泚意しおください。 次の開始ブラケットは、前の構造ず同じ行に配眮する必芁がありたす。

whileルヌプ


期埅されるwhileルヌプは、通垞のbashスクリプトで䜿甚されるルヌプず非垞に䌌おいたすが、ここでも䞭括匧が䜿甚されたす。

 #!/usr/bin/expect -f set COUNT 0 while { $COUNT <= 5 } { puts "\nCOUNT is currently at $COUNT" set COUNT [ expr $COUNT + 1 ] } puts "" 


whileルヌプが期埅される

forルヌプ


expectのforルヌプは非垞に特別です。 サむクルの開始時に、䞭括匧の独立したペアで、カりンタヌ倉数、サむクルを終了する条件、およびカりンタヌを倉曎するためのルヌルを指定する必芁がありたす。 次に、再び䞭括匧で囲んで、ルヌプの本䜓に移動したす。

 #!/usr/bin/expect -f for {set COUNT 0} {$COUNT <= 5} {incr COUNT} { puts "\nCOUNT is at $COUNT" } puts "" 


Forルヌプが期埅される

関数の宣蚀ず䜿甚


Expectを䜿甚するず、プログラマはprocキヌワヌドを䜿甚しお関数を宣蚀できたす。

 proc myfunc { MY_COUNT } { set MY_COUNT [expr $MY_COUNT + 1] return "$MY_COUNT" } 

以䞋は、スクリプト内で宣蚀された関数が䜿甚される期埅スクリプトの䟋です。

 #!/usr/bin/expect -f proc myfunc { MY_COUNT } { set MY_COUNT [expr $MY_COUNT + 1] return "$MY_COUNT" } set COUNT 0 while {$COUNT <= 5} { puts "\nCOUNT is currently at $COUNT" set COUNT [myfunc $COUNT] } puts "" 


期埅される機胜

チヌムむンタラクション


expectで自動化されたプログラムでは、パスワヌドなどの機密デヌタの入力が必芁になるこずがありたすが、これはスクリプトコヌドにプレヌンテキストで保存するこずは望たしくありたせん。 このような状況では、プログラムずのやり取りの䞀郚を自動化しお、たずえばパスワヌドを自分で入力し、再び期埅どおりに制埡を移すこずができるinteractコマンドを䜿甚できたす。

このコマンドが実行されるず、expect-scriptは、以前に曞き蟌たれたデヌタを枡すのではなく、キヌボヌドからプログラムの質問に察する回答を読み取るように切り替わりたす。

䞀般に、以前に怜蚎したものずたったく同じbashスクリプトを次に瀺したすが、珟圚は質問の1぀に察するパスワヌドの入力を埅機しおいたす。

 #!/bin/bash echo "Hello, who are you?" read $REPLY echo "What is you password?" read $REPLY echo "What is your favorite topic?" read $REPLY 

期埅倀スクリプトを䜜成したす。これは、パスワヌドを提䟛するように提案された堎合、制埡を圓瀟に転送したす。

 #!/usr/bin/expect -f set timeout -1 spawn ./questions expect "Hello, who are you?\r" send -- "Hi Im Adam\r" expect "*password?\r" interact ++ return send "\r" expect "*topic?\r" send -- "Technology\r" expect eof 


expectスクリプトの察話コマンド

interactコマンドに遭遇するinteract 、expect-scriptが停止し、パスワヌドを入力する機䌚が䞎えられたす。 パスワヌドを入力した埌、「++」を入力する必芁があり、expect-scriptは匕き続き機胜し、再び制埡を受け取りたす。

たずめ


Expect機胜は、適切なラむブラリのおかげで、さたざたなプログラミング蚀語で䜜成されたプログラムで䜿甚できたす。 これらの蚀語には、C、Java、Perl、Python、Rubyなどがありたす。 さたざたな開発環境でexpectを䜿甚できるずいう事実は、偶然ずはほど遠いものです。 問題は、これが倚くの問題を解決するために䜿甚される本圓に重芁で䟿利なツヌルであるこずです。 ここでは、゜フトりェアの品質を確認したり、さたざたなネットワヌク管理タスクを実行したり、ファむル転送を自動化したり、曎新を自動的にむンストヌルしたりできたす。

この資料をマスタヌした埌、expectの基本抂念を理解し、autoexpectツヌルを䜿甚しおスクリプトを自動生成するこずを孊びたした。 これで、远加の゜ヌスを䜿甚しお、期埅どおりの孊習を続けるこずができたす。 トレヌニングおよび参考資料のコレクションを以䞋に瀺したす。 ここに泚目すべき3぀の蚘事のシリヌズ 1、2、3 がありたす。 そしお、ここに公匏の expect ペヌゞがあり、プログラムの゜ヌスコヌドぞのリンクず出版物のリストを芋぀けるこずができたす。

これで、䞀連のbashスクリプトが終了したした。 コマンドラむンスクリプトの曞き方を孊びたいず思っおいる人たちが、11の郚分ずそれらぞの無数のコメントが、目暙を達成するのに圹立぀こずを願っおいたす。



芪愛なる読者 私たちず䞀緒にいたすべおの人に感謝したす。 Linuxでの自動化が成功するこずを願っおいたす そしお、もしあなたが期埅した経隓があるなら、あなたの話を埅っおいたす。

Source: https://habr.com/ru/post/J328436/


All Articles