Jump to content

Trouble reading output


Recommended Posts

Hey Guys

 

I am struggling reading output from a command line system, I wish to make decisions based upon what is read.

 

The first attempt at reading is successful but the second is just blank...

 

 

Local $iPID= Run("C:\Program Files (x86)\PuTTY\plink.exe 10.xxx.xxx.xxx -ssh", "", @SW_HIDE, 2);





If @error Or Not $iPID Then Exit
Local $sStdOut = ""

Do
    Sleep(10)
    $sStdOut &= StdoutRead($iPID)
Until @error
MsgBox(0, 'System says:', $sStdOut)


;$Message = StdoutRead($iPID)
MsgBox(0, "attempting login", "Sending username",5)
    Sleep (10)
    StdinWrite($iPID, $username & @CRLF)
    Sleep (500)
    StdinWrite($iPID, $username & @CRLF)



Local $sStdOut2 = ""
    Do
    Sleep(10)
    $sStdOut2 &= StdoutRead($iPID)

Until @error

$Message = StdoutRead($iPID)
MsgBox(0, 'System says:', $sStdOut2)

 

Link to comment
Share on other sites

Sorry guys, I tidied up the code:

 

Local $iPID= Run("C:\Program Files (x86)\PuTTY\plink.exe xx.xx.xx.xxx -ssh", "", @SW_HIDE, 2);





If @error Or Not $iPID Then Exit
Local $sStdOut = ""

Do
    Sleep(10)
    $sStdOut &= StdoutRead($iPID)
Until @error
MsgBox(0, 'System says:', $sStdOut)


;$Message = StdoutRead($iPID)
MsgBox(0, "attempting login", "Sending username",5)
    Sleep (10)
    StdinWrite($iPID, $username & @CRLF)
    Sleep (500)
    StdinWrite($iPID, $password & @CRLF)



Local $sStdOut2 = ""
    Do
    Sleep(10)
    $sStdOut2 &= StdoutRead($iPID)

Until @error


MsgBox(0, 'System says:', $sStdOut2)

Apologies, I tidied up the code:

 

Local $iPID= Run("C:\Program Files (x86)\PuTTY\plink.exe 10.xxx.xxx.xxx -ssh", "", @SW_HIDE, 2);





If @error Or Not $iPID Then Exit
Local $sStdOut = ""

Do
    Sleep(10)
    $sStdOut &= StdoutRead($iPID)
Until @error
MsgBox(0, 'System says:', $sStdOut)


;$Message = StdoutRead($iPID)
MsgBox(0, "attempting login", "Sending username * password",5)
    Sleep (10)
    StdinWrite($iPID, $username & @CRLF)
    Sleep (500)
    StdinWrite($iPID, $password & @CRLF)



Local $sStdOut2 = ""
    Do
    Sleep(10)
    $sStdOut2 &= StdoutRead($iPID)

Until @error


MsgBox(0, 'System says:', $sStdOut2)

 

Link to comment
Share on other sites

52 minutes ago, JimmyBman said:

Sorry guys, I tidied up the code:

 

Local $iPID= Run("C:\Program Files (x86)\PuTTY\plink.exe xx.xx.xx.xxx -ssh", "", @SW_HIDE, 2);





If @error Or Not $iPID Then Exit
Local $sStdOut = ""

Do
    Sleep(10)
    $sStdOut &= StdoutRead($iPID)
Until @error
MsgBox(0, 'System says:', $sStdOut)


;$Message = StdoutRead($iPID)
MsgBox(0, "attempting login", "Sending username",5)
    Sleep (10)
    StdinWrite($iPID, $username & @CRLF)
    Sleep (500)
    StdinWrite($iPID, $password & @CRLF)



Local $sStdOut2 = ""
    Do
    Sleep(10)
    $sStdOut2 &= StdoutRead($iPID)

Until @error


MsgBox(0, 'System says:', $sStdOut2)

Apologies, I tidied up the code:

 

Local $iPID= Run("C:\Program Files (x86)\PuTTY\plink.exe 10.xxx.xxx.xxx -ssh", "", @SW_HIDE, 2);





If @error Or Not $iPID Then Exit
Local $sStdOut = ""

Do
    Sleep(10)
    $sStdOut &= StdoutRead($iPID)
Until @error
MsgBox(0, 'System says:', $sStdOut)


;$Message = StdoutRead($iPID)
MsgBox(0, "attempting login", "Sending username * password",5)
    Sleep (10)
    StdinWrite($iPID, $username & @CRLF)
    Sleep (500)
    StdinWrite($iPID, $password & @CRLF)



Local $sStdOut2 = ""
    Do
    Sleep(10)
    $sStdOut2 &= StdoutRead($iPID)

Until @error


MsgBox(0, 'System says:', $sStdOut2)

 

 

Link to comment
Share on other sites

1 minute ago, JimmyBman said:

Thanks so much RM

 

That looks like it might solve things for me, I spent ages looking for examples

No worries I just finished using it to check various devices on our network etc / auto compiling reports when devices error out etc... :D VERY USEFUL

Link to comment
Share on other sites

19 hours ago, JimmyBman said:

I am struggling reading output from a command line system, I wish to make decisions based upon what is read.

The first attempt at reading is successful but the second is just blank...

...when you use a loop like this:

Do
    Sleep(10)
    $sStdOut &= StdoutRead($iPID)
Until @error
MsgBox(0, 'System says:', $sStdOut)


the Until @error part works like this :
the @arror occurs when you try to read with StdoutRead() from a process that is no more running. So if the error occurs it means that the process has finished and you have no more data to read. The whole otput is already in the $sStdOut variable.
This kind of way to read from StdOut stream is good only when you run a command that will return a single output and then it will end.
In this context the @error will mark the end of the job.
But, if you have to interact with a running process, that is, get part of the output, send something with StdInWrite and so on, then checking @error is not ok, because @error doesn't means "I have finished to send my output", but it means "the process is no more running".
You say: "but the second is just blank..." is because in the second reading loop, the plink.exe is no more running.

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

you can try this two tips to help with debugging
1) use 0x8 as the fourth parameter of the run command (opt_flag) . In this way StOutRead will also capture any error messages. You will be able to better verify what is happening
2) to see if after the first cycle plink.exe is still running, you can insert a ProcessExist () right after the cycle, something something like this:

If Not ProcessExists($iPID) Then MsgBox(0, "Info", "Your process is over")

P.S.

also, if you want write to Input stream of the process with the StdInWrite() function, you have to enable the StdInput stream of the runned process by also enabling the $STDIN_CHILD(0x1) flag when you run your process, so, the fourth parameter of the run command shuld be 0x9 (that is $STDERR_MERGED (0x8) + $STDIN_CHILD (0x1) )

Edited by Chimp
added a p.s.

 

image.jpeg.9f1a974c98e9f77d824b358729b089b0.jpeg Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Link to comment
Share on other sites

Hey Chimp

 

Thanks for your help above, I have only managed to get back to looking at this today. Getting further - I now have the correct statements for running the process.

Now, while I can read from the system I can only do so when embedding that part inside a loop, a loop which I can't seem to manage correctly...

 

Is there a simple trick I am missing, do I need to have a continuous loop running to keep reading output into a variable, at the moment it loops back to the start, THEN and only then can I see the variable being filled with output. but i'm stuck in a loop of sending credentials over and over.

 

Sorry, this is probably really basic stuff to you and I do appreciate your help.

 

 

Local $iPID = Run("C:\Program Files (x86)\PuTTY\plink.exe 10.33.21.xxx -ssh", "", @SW_HIDE,$STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)



If Not ProcessExists($iPID) Then
    MsgBox(0, 'System says:', "process dead")
    EndIf



If @error Or Not $iPID Then Exit


Local $StdOut = ""




While ProcessExists($iPID)
    $StdOut &= StdoutRead($iPID)&@CRLF

;If $stdOut >= True Then ExitLoop
MsgBox(0, 'System says1:', $StdOut)

MsgBox(0, "attempting login", "Sending username",5)
    Sleep (5000)
    StdinWrite($iPID, $username & @CRLF)
    Sleep (5000)
    StdinWrite($iPID, $password & @CRLF)
    Sleep (6000)
    StdinWrite($iPID, "TEST LINE" & @CRLF)
    Sleep (6000)


MsgBox(0, 'System says2:', $StdOut)


Sleep (6000)
WEnd

 

Link to comment
Share on other sites

Maybe this will help...


 

Spoiler
#include <AutoItConstants.au3>

Global $iPID = Run("C:\Program Files (x86)\PuTTY\plink.exe 10.33.21.xxx -ssh", "", @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD + $STDERR_CHILD)

If Not ProcessExists($iPID) Then
    MsgBox(0, 'System says:', "process dead")
EndIf

If @error Or Not $iPID Then Exit

Global $StdOut = ""
Global $bLogin = False

While ProcessExists($iPID)
    $StdOut = GrabStdOut($iPID)

    If @error Then ExitLoop
    ConsoleWrite('System says1: ' & $StdOut & @CRLF)

    If Not $bLogin Then
        $bLogin = Login($iPID, "USER1", "PA55W0RD")
    EndIf

    $StdOut = GrabStdOut($iPID)

    If @error Then ExitLoop
    ConsoleWrite('System says2: ' & $StdOut & @CRLF)
    Sleep(1000)
WEnd

Func Login($iPID, $sUsername, $sPassword, $iWait = 6000)
    ConsoleWrite("Attempting login, Sending username: " & $sUsername & @CRLF)
    
    StdinWrite($iPID, $sUsername & @CRLF)
    Sleep($iWait)
    StdinWrite($iPID, $sPassword & @CRLF)
    Sleep($iWait)

    Local $sStdOut = GrabStdOut($iPID, True) ;Only Peek stdout that means data is not erased
    If @error Then Return False
    ;Check if Login succeeded here.. set Return true if so..
    Return True
EndFunc   ;==>Login

Func GrabStdOut($iPID, $bPeek = False, $iRetrySecs = 5)
    ;$bPeek If True the function does not remove the read characters from the stream
    ;$iRetrySecs number of seconds to wait with no data before giving up
    Local $sStdOut = "", $iErr = 0, $iSecsLeft = $iRetrySecs
    If Not ProcessExists($iPID) Then $iErr = 0xBAD ; 2989 just something markedly different from error code from StdoutRead
    While $iErr = 0 ;
        If $bPeek Then $sStdOut = "" ;Comment out if you lose data
        $sStdOut &= StdoutRead($iPID, $bPeek) & @CRLF;
        $iErr = @error ;@error should be stored before running other commands
        ;If @extended = 0 Or $bPeek Then ;if $bPeek makes @extended continually return chars read
        If @extended = 0 Then; No characters were read
            If $iSecsLeft <= 0 Then ExitLoop ;Nothing to be read time to return output
            Sleep(1000) ; wait 1 second
            $iSecsLeft -= 1 ;Countdown
        Else;
            $iSecsLeft = $iRetrySecs ;Got data reset countdown
        EndIf;
    WEnd;

    Return SetError($iErr, StringLen($sStdOut), $sStdOut) ;Pass back data @extended contains string length
EndFunc   ;==>GrabStdOut

 

 

Edited by Bilgus
Link to comment
Share on other sites

  • 2 weeks later...

Hi @Bilgus

 

Once again I wanted to thank you for the above code. It's helped me understand what was happening far more clearly. I have only just had time now to look at this again (my job allows for little time to be spent on this). I seem to be getting stuck inside the GrabStdOut function as below.

 

I get as far as being prompted for the login details (which I can see on the console as read by the grab part the first time round). Then I send my creds, the main loop goes around again but I seem to get stuck on the "While $iErr = 0" line after that point. I have varied the $iRetrySecs to a few different settings to no avail...

 

Func GrabStdOut($iPID, $bPeek = False, $iRetrySecs = 1)
    ;$bPeek If True the function does not remove the read characters from the stream
    ;$iRetrySecs number of seconds to wait with no data before giving up
    ConsoleWrite("1")
    Local $sStdOut = "", $iErr = 0, $iSecsLeft = $iRetrySecs
    ConsoleWrite("2")
    If Not ProcessExists($iPID) Then $iErr = 0xBAD ; 2989 just something markedly different from error code from StdoutRead
   ConsoleWrite("3")
   While $iErr = 0 ;
       ConsoleWrite("4")  |||||||||||||||>>>>>> I seem to get endless 4s HERE <<<<<<<<<<|||||||||||
        If $bPeek Then $sStdOut = "" ;Comment out if you lose data
        $sStdOut &= StdoutRead($iPID, $bPeek) & @CRLF;
        $iErr = @error ;@error should be stored before running other commands
        ;If @extended = 0 Or $bPeek Then ;if $bPeek makes @extended continually return chars read
        If @extended = 0 Then; No characters were read
            If $iSecsLeft <= 0 Then ExitLoop ;Nothing to be read time to return output
            Sleep(1000) ; wait 1 second
            $iSecsLeft -= 1 ;Countdown
        Else;
            $iSecsLeft = $iRetrySecs ;Got data reset countdown
        EndIf;
    WEnd;

 

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...