Jump to content

expect-tation


Recommended Posts

Hey guys

I've been using autoit for more than a year now... and i just registered to the forum because i stumbled onto a small hurdle...

is there a way to have autoit 'wait for event'?

for example i mainly use autoit to setup solaris servers. it would be gret to have a function that once you receive a string, rather than waiting a certain amount of time (Sleep() function) having a function like WaitString("any_string_you_want") and then do a Send() if the string is received

thanks!

Link to comment
Share on other sites

Hi,

you mean usinf a loop and checking a variable ervery e.g. 200 ms for containing a special string?

Mega

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

not exactly...

ok... here is a simple MANUAL scenario

start -> putty.exe

then i select my server and click on OPEN

a terminal session opens and i get the "login as: " string/prompt

i enter my username and then i get a "Password: " string/prompt

I can automate this very simply with the Sleep() function. the problem is depending on the load of the server, it can take more time to send the prompt then the amoutn of time i put in the Sleep()

in so many words, if you take a look at the expect application http://expect.nist.gov/ and more specificaly at the example at http://www.gnulamp.com/expect.html (bottom of the page) you'll understand what i mean!

thanks!

Link to comment
Share on other sites

Hi,

there are several other tools to do it like plink, pscp and so on without the GUI.

For starting putty and then choosing a server you could use :

#include <string.au3>
Opt("WinTitleMatchMode", 4)

Global $sUsername = @UserName
Global $SLoginServer = 'xxx'
Global $sPassword = 'xxx'

;AutoItSetOption ( "ExpandVarStrings", 0 )
Run('"' & @ComSpec & '" /c putty -ssh', '', @SW_HIDE)
WinWaitActive('[CLASS:PuTTYConfigBox]', '', 5)
ControlSend('[CLASS:PuTTYConfigBox]', '', 1008, "+{TAB}" & "Ses" & "{TAB}")
ControlSetText('[CLASS:PuTTYConfigBox]', '', 1044, $sUsername & "@" & $SLoginServer)
ControlClick('[CLASS:PuTTYConfigBox]', '', 1009, 'left', 1)
WinWaitActive('[CLASS:PuTTY]', '', 5)
;~ Sleep(2500)
If ControlSend('[CLASS:PuTTY]', '', '', $sPassword & '{ENTER}') Then _log("Password sent")
Func _log($text)
    ConsoleWrite($text & @CRLF)
EndFunc

Mega

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

Mega,

I know all this and my script looks like it too... all i want to get rid of is the Sleep() function!

i fit were an expect script it would be like:

#!./expect -f

spawn ftp $argv

expect "Name"

send "anonymous"

expect "Password:"

send "mypasswdr"

interact

in so many words, autoit would constantly monitor the output stream of the window and when it receives a particular string (in this case for example 'Name') then it would trigger a Send() function with a username.

Link to comment
Share on other sites

Hi,

is it really putty or is it another window? You WinGetText(), right?

Mega

Scripts & functions Organize Includes Let Scite organize the include files

Yahtzee The game "Yahtzee" (Kniffel, DiceLion)

LoginWrapper Secure scripts by adding a query (authentication)

_RunOnlyOnThis UDF Make sure that a script can only be executed on ... (Windows / HD / ...)

Internet-Café Server/Client Application Open CD, Start Browser, Lock remote client, etc.

MultipleFuncsWithOneHotkey Start different funcs by hitting one hotkey different times

Link to comment
Share on other sites

The application to connect to the server is not important. the connection could be made by telnet from a doc cmd window, an ftp session, anything interactive...

i will take a look at the WinGetText() function and see if it can do what i want...

i'll ley u know!

thanks!

Link to comment
Share on other sites

i just took a look a the function and the example along with it:

$text = WinGetText("Untitled -", "")

MsgBox(0, "Text read was:", $text)

now if i try to set it up in a script it would be like set this in a loop and exit if $text = "login as: " and once out Send("username{ENTER}")

would that do it?

Link to comment
Share on other sites

  • 4 months later...

Hi,

I add the same problem.

Try this: I am not a great developper but it works for me, so I think it can help you.

You need to download plink.exe, and to put it in the same folder than the script.

Note: you cannot use the expect function 2 times, if you don't use expSend.

#include <Constants.au3>

$ip="192.168.1.1"
$flux_out = Run(@ComSpec& ' /c plink -telnet '&$ip&' ' ,@WorkingDir,@SW_HIDE, $STDIN_CHILD + $STDERR_CHILD + $STDOUT_CHILD)

expect($flux_out, "login", 3)
expSend($flux_out, "mylogin")
expect($flux_out, "Password", 3)
expSend($flux_out, "mypassword")  
expSend($flux_out, "/sbin/route")
expect($flux_out, "routing", 3)
expSend($flux_out, "exit")

MsgBox(0, "", "End of script")
Exit 0



Func expect ($process, $expectedString, $timeout) 
    ConsoleWrite ("Expect : '"&$expectedString& "', with timeout: "&$timeout & @CRLF)
    
    $rep_err=""
    $rep_ok=""
    
    For $i = 1 to $timeout
        $rep_err &= StderrRead($process)
        ConsoleWrite ("StderrRead: "&$rep_err & @CRLF)  
        If @error Then 
            MsgBox(0, "Error : STDERR read:", $rep_err)
            ExitLoop
        EndIf
   
        $rep_ok &= StdoutRead($process)
        ConsoleWrite("StdoutRead: "&$rep_ok & @CRLF)
        If @error Then 
            MsgBox(0, "Error : STDOUT read:", $rep_err)
            ExitLoop
        EndIf
        
        If StringInStr($rep_ok,$expectedString)<>0 Then
        ConsoleWrite ("Expected string : '"&$expectedString& "' found" & @CRLF) 
            Return 1
        EndIf
        
        Sleep (1000)
    Next

    ConsoleWrite ("FAILED, Expected string '"&$expectedString&"' not found " & @CRLF)   
    ConsoleWrite ("StdoutRead : "& $rep_ok & @CRLF) 
    MsgBox(0, "", "FAILED, Expected string '"&$expectedString&"' not found ", 2)
    Return 0
EndFunc



Func expSend ($process, $inputText)
    ConsoleWrite ("expSend : "& $inputText & @CRLF) 
    StdinWrite($process, $inputText & @CR )
EndFunc

Regards,

ch'Man

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...