Expect: Difference between revisions
Line 128: | Line 128: | ||
Eelnevas näites kasutatud \ rea lõpus tähendab seda, et käsk jätkub, st. et kui expecte oleks selles näites rohkem olnud siis peab kõigi ridade, peale viimase, lõpus olema \. | Eelnevas näites kasutatud \ rea lõpus tähendab seda, et käsk jätkub, st. et kui expecte oleks selles näites rohkem olnud siis peab kõigi ridade, peale viimase, lõpus olema \. | ||
Sama | Sama näidet saab kujutada ka kujul: | ||
<pre> | <pre> | ||
expect { | expect { |
Revision as of 16:35, 26 December 2011
Koostamisel...
Sissejuhatus
Expect on Don Libes'i poolt kirjutatud Tcl (Tool Command Language) laiendus, mida kasutatakse erinevate käsurea tegevuste automatiseerimiseks. Põhiliselt kasutatakse expect'i käsurealt kasutatavate inetaktiivsete rakenduste (ssh, telnet, ftp, sudo jne) automatiseerimiseks. Expect on asendamatu abimees neile, kes tahavad automatiseerida näiteks paroolide muutmist, võrguseadmete haldamist vms tegevust, mis nõuab kasutaja-terminali vahelist suhtlust. Piltlikult võib öelda, et kasutades etteantud skripti expect "räägib" teiste interaktiivsete programmidaga. Järgides skripti expect teab mida programmilt oodata ja mida programmile erinevates olukordades "öelda".
Üldine
Expecti põhiliseks alustalaks on kolm käsku: expect, send ja spawn. Samuti on tihti suureks abiks käsk interact. Expect ootab teatud andmeid protsessilt. Send käsk saadab andmed protsessile. Spawn alustab protsessi. Interact annab juhtimise üle kasutajale.
Järgneva artikli paremaks mõistmiseks peaks olema eelnevalt tuttav Linuxi käsureaga.
Expect interpretaatori käivitamiseks sisesta käsureale:
expect
tulemus:
expect1.1>
Send
Send käsk loeb etteantud stringi kui argumenti ja saadab selle protsessile. Näiteks:
send "tere maailm"
Eelneva puhul saadetakse string tere maailm. Kui expect juba suhtleb mõne programmiga siis saadetakse string sellele programmile. Hetkel saadetakse see aga standard väljundisse. Kasutades expect interpretaatorit, näeks tulemus välja selline:
tere maailmexpect1.2>
Send käsk ei muuda string formaati ja seega peale selle esitamist liidetakse otsa expecti prompt. Selleks, et prompt prinditaks uuele reale on vaja lisada stringi lõppu reavahetuse sümbol \n.
send "tere maailm\n"
tere maailm
expect1.2>
Kui eelnev send käsk lisada faili (nt. nimega test), saab skripti käivitada UNIXi käsurealt.
expect test
Mõningase faili muutmisega saab aga skripti käivitada ka ilma expecti lisamata. Selleks lisa faili algusesse expecti asukoht:
#!/usr/bin/expect
ja muuda fail käivitatavaks:
chmod +x test
Nüüd saad skripti käivitada ka käsuga:
./test
Expect
Expect on vastupidine send'le. Expect ootab vastust programmilt või kasutajalt. Expect võib oodata kindlat stringi või ka osa teadaolevast stringist. Näiteks loome faili "vestlus" alloleva sisuga ja anname talle käivitamise õigused.
#!/usr/bin/expect
expect "tere\n"
send "tere ise ka!\n"
Käivitme skripti
./vestlus
Juhtub see, et programm ootama stringi tere ja reavahetust (\n). Kirjutades käsureale tere ja vajutades enterit väljastatakse vastuseks tere ise ka!.
expect_out(0,string)/expect_out(buffer)
Expect jääb oodatavat stringi ootama seniks kuni see sisetatakse. Kui kasutada eelnevat skripti ja sisestada tereasemel näiteks hello siis expect ei väljasta midagi ja jääb endiselt ootama teresisestamist. Kui sisestada lõpuks ka oodatav string (tere) siis expect vastab. Enne vastamist aga salvestab expect sobinud märgid muutujasse expect_out(0,string). Sobinud märgid ning lisaks kõik sellele eelnevalt sisestatud märgid salvestatakse muutujasse expect_out(buffer). Eelnevat tehakse iga kord kui expect tuvastab sobinud märgid.
Muudame eelneva skripti vestlus sisu järgnevaks:
#!/usr/bin/expect
expect "tere"
send "sina sisestasid <$expect_out(buffer)>"
send "oodatud string oli <$expect_out(0,string)>"
Nurksulud ei ole iseenesest vajalikud aga teevad väljundi lugemise lihtsamaks - parem on aru saada kus algavad ja lõpevad muutujad.
Kui skript käivitada ja sisetada näiteks:
hei, tere
väljastatakse tulemuseks:
sina sisestasid <hei, tere>
oodatud string oli <tere>
Ankrud
Nagu enne mainitud ei ole mittesobituva info leidmine sisendis expecti jaoks probleem. Sisendi jälgmist jätkatakse kuni sobitumiseni. Vahel on aga vaja aga piirata mittevajalike sümbolite ilmumist sisendisse.
^ kasutatakse juhul kui on vaja sobitumist sisendi alguses. Näiteks ^hei sobitub kui kirjutada sisendisse hein aga ei sobitu sisendiga juhhei
$ kasutatakse juhul kui on vaja sobitumist sisendi lõpus. Näiteks hei$ sobitub sisendiga juhhei kuid mitte hein. Järelikult ^hei$ ei sobitu kummagagi, vaid ainult hei'ga.
Timeout
Vaikimisi ootab expect sobituvat sisendit 10 sekunidit. Kui selle aja jooksul sobitumist ei toimi siis expect lõpetab. Loomilikult saab timeouti ka muuta. Selleks on käsk:
set timeout 60
Eelnev määrab timeoudiks 60 sekundit.
Üldiselt peab olema timeout positiivne arv. On aga paar erandit.
0 määrab, et expect ei peaks ootama üldse.
-1 määrab, et excpect peaks ootama igavesti.
Expect-Send paarid
Expect-Send paaride korral kirjeldatakse Expect, mida oodatakse ja selle järele kohe Send mis peaks sobitumisel väljastatama.
Näide 1:
expect "tere" {send "$expect_out(buffer)"}
Selle näite puhul jääb expect ootama tere sisestamist ja kui see on sisestatud siis väljastab kogu sisestatud teksti mis sellele eelnes ja tere.
Näide 2:
expect "tere" { send "tere ise ka!\n" }\ "hei" { send "hei sullegi!\n" }
Selle näite puhul oodatakse üheaegselt nii tere kui ka hei sobitumist. Täide viiakse see send, mille ees olev expect esimesena sobitub. Kui ükski expect ei sobitu enne timeout aega siis expect lõpetab selle lause ning jätkab skripti järgmise käsu täitmisega.
Expect koodis ei ole vahet kuidas expect ja send visuaalselt paigutatud on. Põhimõtteliselt võib koodi esitada ka ühe pika reana kuigi eraldi ridadel on expect-send paare parem lugeda. Silmas tuleb pidada vaid seda, et send käsud peavad olema loogeliste sulgude sees.
Eelnevas näites kasutatud \ rea lõpus tähendab seda, et käsk jätkub, st. et kui expecte oleks selles näites rohkem olnud siis peab kõigi ridade, peale viimase, lõpus olema \.
Sama näidet saab kujutada ka kujul:
expect { "tere" { send "tere ise ka!\n" } "hei" { send "hei sullegi!\n" } }
Koostab
Meelis Kurnikov AK21