Expect
Expect je rozšíření skriptovacího jazyka Tcl určené pro automatizaci práce s programy, které interaktivně používají rozhraní příkazového řádku. Expect vytvořil v roce 1990 Don Libes pro unixové systémy, ale od té doby byl přenesen i na Microsoft Windows a jiné systémy.
Vývojář | Nils Carlson |
---|---|
Aktuální verze | 5.45.1 (2012-08-15) |
Operační systém | POSIX, Windows |
Vyvíjeno v | Tcl |
Typ softwaru | svobodný software, command line interface language, programovací jazyk a autoclick |
Licence | Svobodný software[1] |
Web | expect |
Některá data mohou pocházet z datové položky. |
Úvod
Expect se používá pro automatizaci řízení interaktivních aplikací, jako je telnet, FTP, passwd, fsck, rlogin, tip, SSH a dalších. Expect používá pseudoterminály v Unixu nebo emulaci konzole ve Windows pro spuštění požadovaného programu, se kterým pak komunikuje pomocí terminálu nebo konzolového rozhraní podobně jako by to dělal člověk. Výsledkem může být úplná automatizace činnosti nebo například poskytnutí grafického uživatelského rozhraní uživateli (při použití Tk).
Expect disponuje mechanismem regulárních výrazů pro vyhledávání vzorků a obecnou programovou funkcionalitou, která umožňuje jednoduchým skriptům inteligentně řídit programy, které nemají programovací jazyk, makra nebo jiný mechanismus pro programování.
Použití
Expect slouží jako „lepidlo“ umožňující propojit dohromady existující programy, které nebyly navrženy, aby vzájemně spolupracovaly. Obecně je vhodné využít co nejvíce funkcionality existujících nástrojů, než řešit problémy v Expectu.
Důležitou doménou pro Expect jsou komerční softwarové produkty. Mnoho programů poskytuje ovládání pomocí příkazového řádku, ale často neumožňují psaní skriptů. Byly navrženy, aby umožňovaly správu určitého zařízení, ale výrobce často nevynaložil dostatek prostředků na plnou implementaci robustního skriptovacího jazyka. Skript v Expectu může spustit shell, používat proměnné prostředí, provádět některé unixové příkazy pro načtení dalších informací a pak vstoupit do prostředí příkazového řádku programu s nezbytnými informacemi pro dosážení záměru uživatele. Po shromáždění potřebných informací v příkazovém řádku programu může skript provést inteligentní rozhodnutí o tom, zda provést nějakou akci, a jak.
Pokaždé, když Expect dokončí operaci, jsou výsledky uloženy do lokální proměnné $expect_out
. To skriptu umožňuje shromáždit informace potřebné pro uživatele, a zároveň rozhodnout o dalším chování skriptu.
Expect se často používá pro vytváření testů programů, utilit nebo vestavěných systémů. Příkladem testovacího nástroje napsaného v Expectu je DejaGnu, který byl intenzivně používán pro testování GCC, a je velmi vhodný i pro testování na vzdálených strojích například při vývoji vestavěných systémů.
Pro automatizaci vytváření expect skriptů lze použít nástroj nazývaný autoexpect, který sleduje činnost uživatele a pomocí heuristik vytváří skript v expectu. Přestože vygenerovaný kód může být rozsáhlý a hůře srozumitelný, lze se jím inspirovat nebo jej upravit na lepší kód.
# Proměnné $remote_server, $my_user_id, $my_password a $my_command musí být
# již nastaveny dříve ve skriptu.
# Otevřít spojení telnetem na server, a počkat na výzvu k zadání uživatelského jména
spawn telnet $remote_server
expect "username:"
# Poslat uživatelské jméno a čekat na výzvu na zadání hesla
send "$my_user_id\r"
expect "password:"
# Poslat heslo a čekat na výzvu shellu
send "$my_password\r"
expect "%"
# Poslat požadovaný příkaz a znovu čekat na výzvu shellu
send "$my_command\r"
expect "%"
# Výsledky uložit do proměnné results pro pozdější zobrazení nebo uložení do souboru
set results $expect_out(buffer)
# Ukončit telnetové spojení a čekat na ukončení vstupu
send "exit\r"
expect eof
Dalším příkladem je skript, který automatizuje FTP:
# Nastavte parametr timeout (prodleva) na vhodnou hodnotu;
# pokud je např. soubor velmi velký a síť pomalá, je třeba
# hodnotu parametru dobře vyladit.
set timeout -1
# Otevřít ftp spojení na server a počkat na výzvu k zadání uživatelského jména
spawn ftp $remote_server
expect "username:"
# Poslat uživatelské jméno a čekat na výzvu na zadání hesla
send "$my_user_id\r"
expect "password:"
# Poslat heslo a čekat na výzvu programu FTP
send "$my_password\r"
expect "ftp>"
# Přepnout to binárního režimu a počkat na výzvu programu FTP
send "bin\r"
expect "ftp>"
# Vypnout vypisování dotazů
send "prompt\r"
expect "ftp>"
# Načíst všechny soubory
send "mget *\r"
expect "ftp>"
# Ukončit FTP spojení a čekat na ukončení vstupu
send "bye\r"
expect eof
Následuje příklad, který ukazuje automatizaci použití SFTP (s heslem):
#!/usr/bin/env expect -f
# procedura pro připojení; výsledek je 0 při úspěchu, 1 jinak
proc connect {passw} {
expect {
"Password:" {
send "$passw\r"
expect {
"sftp*" {
return 0
}
}
}
}
# timed out
return 1
}
# načti vstupní parametry
set user [lindex $argv 0]
set passw [lindex $argv 1]
set host [lindex $argv 2]
set location [lindex $argv 3]
set file1 [lindex $argv 4]
set file2 [lindex $argv 5]
#puts "Argument data:\n";
#puts "user: $user";
#puts "passw: $passw";
#puts "host: $host";
#puts "location: $location";
#puts "file1: $file1";
#puts "file2: $file2";
# kontrola, jestli máme všechno
if { $user == "" || $passw == "" || $host == "" || $location == "" || $file1 == "" || $file2 == "" } {
puts "Usage: <user> <passw> <host> <location> <file1 to send> <file2 to send>\n"
exit 1
}
#sftp to specified host and send the files
spawn sftp $user@$host
set rez [connect $passw]
if { $rez == 0 } {
send "cd $location\r"
set timeout -1
send "put $file2\r"
send "put $file1\r"
send "ls -l\r"
send "quit\r"
expect eof
exit 0
}
puts "\nError connecting to server: $host, user: $user and password: $passw!\n"
exit 1
Předávání hesel jako pomocí parametrů příkazů použité v tomto příkladě, je bezpečnostní díra, protože jiní uživatelé na stejném počítači mohou heslo zjistit pomocí příkazu ps
. Je však možné kód upravit, aby poslal heslo po vypsání výzvy:
stty -echo
send_user -- "Enter Password: "
expect_user -re "(.*)\n"
send_user "\n"
stty echo
set PASS $expect_out(1,string)
Tento postup je bezpečnější, ale stále je problémem uložení nezašifrovaného hesla v textu skriptu.
Další příkladem je automatizované přihlášení uživatele na počítač pomocí ssh:
# timeout is a předdefinovaná proměnná v expectu nastavená na 10 sec
# spawn_id je další implicitně používaná proměnná v expectu.
set timeout 60
spawn ssh $user@machine
while {1} {
expect {
eof {break}
"The authenticity of host" {send "yes\r"}
"password:" {send "$password\r"}
"*\]" {send "exit\r"}
}
}
wait
# Je vhodné zavřít spawn_id handle vytvořené příkazem spawn:
close $spawn_id
Alternativy
Různé projekty implementují funkčnost podobnou Expectu v jiných jazycích – C#, Java, Scala, Groovy, Perl, Python, Ruby, Shell a Go. Obecně se nejedná o přesné klony původního Expectu, ale často se mu velmi podobají.
C#
- Expect.NET – funkčnost Expectu pro C# (.NET)
- DotNetExpect – Expectem inspirovaná knihovna pro automatizaci konzolových programů pro .NET
Java
- expect4j – pokus o klon původního Expectu v jazyce Java
- ExpectJ – další implementace unixového programu expect v jazyce Java
- Expect-pro-Java – čistě javová implementace nástroje Expect
- expect4java – javová implementace nástroje Expect, která podporuje vnořené clousures. Existuje také wrapper pro Groovy DSL.
Scala
- scala-expect – implementace velmi malé podmnožiny funkčnosti nástroje Expect pro jazyk Scala.
Groovy
- expect4groovy – implementace nástroje Expect pro Groovy DSL.
Perl
- Expect.pm – Perlový modul (nejnovější verze je na metacpan.org)
Python
- Pexpect – modul pro Python pro řízení interaktivních programů v pseudoterminálu
- winpexpect – port pexpect na platformu Windows
Ruby
Shell
- Empty – program podobný Expectu pro spouštění interaktivních příkazů v unixových shellových skriptech
Odkazy
Reference
V tomto článku byl použit překlad textu z článku Expect na anglické Wikipedii.
- Expect FAQ: Our company policy requires a license to use Expect. Where can we get a license? [online]. Dostupné online.
Literatura
- LIBES, Don. Exploring Expect: A Tcl-Based Tool for Automating Interactive Programs. planeta Země: O'Reilly & Associates, Inc, 1995. Dostupné online. ISBN 1-565-92090-2.
- "Advanced Programming in Expect: A Bulletproof Interface"
Externí odkazy
- Slovníkové heslo expect ve Wikislovníku
- Oficiální website
- Expect na SourceForge
- Expect stránka – na Wiki pro uživatele Tcl
- IBM Blog