Expect
Expect – pakiet języka Tcl, który pozwala na interakcję z aplikacjami terminalowymi. Tworzy on własny terminal, który "udaje" użytkownika obsługującego program konsolowy. Choć teoretycznie jest możliwe sterowanie przez Expecta aplikacją w "curses", to najczęściej wykorzystuje się go do sterowania aplikacjami za pomocą prostego odczytywania i wypisywania ciągu znaków - jak np. aplikacje typu powłoka, telnet, czy FTP.
Funkcje pakietu
[edytuj | edytuj kod]Kwestia tego, czy Expect może być po prostu pakietem, zależy od tego, jak aktualnie zainstalowano i skonfigurowano Tcl-a na danej maszynie, dlatego też często istnieje on w najprostszej postaci - jako samodzielny interpreter Tcl-a razem z wbudowanym pakietem Expect, dostępny na Uniksie pod poleceniem "expect". Istnieje również wersja Expect działająca pod kontrolą systemu Microsoft Windows (oferuje go - odpłatnie - ActiveState, ewentualnie można skorzystać z pakietu Cygwin), ale najpowszechniej Expect jest używany na systemach typu POSIX.
Podstawowe komendy
[edytuj | edytuj kod]Podstawowymi komendami Expecta są spawn, send oraz expect. Dla przykładu zaprezentowano, w jaki sposób zrobić skrypt, który sam zaloguje się na zdalny host (zdalny.host.pl) i odczyta zawartość katalogu domowego, po czym wypisze go na ekranie.
Praca z pakietem
[edytuj | edytuj kod]Najpierw uruchamia się podległą aplikację, czyli telnet:
spawn telnet zdalny.host.pl
Komenda ta zapisze w zmiennej spawn_id identyfikator utworzonego połączenia z podległą aplikacją; będą z niej potem korzystać komendy "send" i "expect". Teraz skrypt musi zaczekać, aż zdalny host napisze "login:".
expect "login:"
Komenda ta powoduje cykliczne odczytywanie z kanału, do którego aplikacja usiłuje zapisywać, myśląc, że pisze na terminal. Komenda kończy się, gdy w odczytanym tekście znajdzie się szukany napis.
send "sektor\r"
Tekst musi się kończyć znakiem \r
. W przeciwnym razie ma się taki efekt, jakby ktoś wpisał nazwę użytkownika i zapomniał nacisnąć enter.
Teraz należy czakać na zachętę do hasła. Ponieważ zdarza się, że owo "password" będzie się zaczynało wielką literą, a czasem małą, można pominąć początek słowa i użyć po prostu:
expect "assword:"
I podać hasło
send "wr353fg466s\r"
Powinno się zaczekać na prompt, odczytać wszystko co się da, założyć drobne opóźnienie, żeby nie odczytał za mało. Następnie odczytać sam prompt przez po prostu naciśnięcie enter:
sleep 2
expect *
send \r
expect ">"
Akcja:
send "ls\r"
expect "ls"
expect ">" { set directory $expect_out(buffer) }
Objaśnienie do expect "ls": terminal sam wypisze komendę, którą wpisało się (gdyby tego nie zrobił, byłby efekt podobny do prośby o hasło - po wpisaniu nic nie widać). Następnie trzeba usunąć ostatnią linijkę, którą był prompt i wypisać to na ekranie:
set directory [join [lrange [split $directory \n] 1 end-1] \n]
puts $directory
Objaśnienie dlaczego od 1, nie od 0: było expect "ls", więc znak końca linii pozostał w buforze. Następna po tym komenda expect odczytała z $expect_out(buffer) wszystko co było w buforze, aż do ciągu, który podano w instrukcji expect.
Expect posiada jeszcze wiele ciekawych komend pozwalających na bardziej inteligentne interakcje, ale te pokazane tutaj są używane w przeważającej większości. Z expectem trzeba zawsze trochę poeksperymentować (niestety terminale potrafią sprawiać różne niespodzianki), w czym pomaga opcja -d w poleceniu expect - wtedy na standardowe wyjście diagnostyczne wypisywane są kolejne akcje podejmowane przez expecta.
Nie ma też uniwersalnych rad, jak pisać pod expectem - należy po prostu zaprogramować skrypt, żeby tak rozmawiał z aplikacją, jak robiłby to człowiek. Expect posiada nawet specjalne komendy nadające takie ustawienia, że komenda "send" wpisuje tekst z odpowiednimi nieregularnymi opóźnieniami, udając człowieka.
Autor pakietu
[edytuj | edytuj kod]Autorem Expecta jest Don Libes.