Yaerox

Capture DOS/PuTTY output - StdoutRead just working the first time

5 posts in this topic

#1 ·  Posted (edited)

Hey guys,
 
I want to use Putty/Plink to connect on a remote computer via SSH because I need to execute a couple commands there. So I researched a couple days now and tried like 20 different ways to get this running but I'm still failing. Maybe a little description what my script should do:
 
#Edit: Short version: I need to use StdoutRead to get the DOS command promt output MORE THAN ONCE! The first time is working, but I need to get this the whole time till I say stop ^^
 
I want to start Putty/Plink and connect via SSH on a remote computer AND I wanna check if there is anything wrong going on or not, because the next step would be the execution of an perl-script on the remote computer which is giving an output text while running. That means I'd like to be able to read out the Putty-Window/Plink-Console the whole time ... I'm actual just getting the text-output after connecting.
 
Maybe a little example of what I'm expecting in some kind of mixed "AutoIt/Pseudo -Code":
 
#include <Constants.au3>
Local $iPID = Run('"C:\Program Files (x86)\Putty\putty.exe" -ssh root@HOST:22 -pw PASSWORD', @ScriptDir, @SW_SHOW, $STDERR_CHILD + $STDOUT_CHILD)
 
Actual Putty-Window is popping up showing me:
Using username "root".
Linux COMPUTERNAME 2.6.31-22-generic-pae #63-Ubuntu SMP Wed Aug 18 23:57:18 UTC 2010 i686
 
To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
 
  System information as of Mo 13. Jan 15:01:50 CET 2014
 
  System load:  0.0               Processes:           77
  Usage of /:   47.5% of 9.15GB   Users logged in:     1
  Memory usage: 9%                IP address for eth2: HOST
  Swap usage:   0%
 
  Graph this data and manage this system at https://landscape.canonical.com/
 
Last login: Mon Jan 13 14:58:43 2014 from XXX.X.X.XXX
root@COMPUTERNAME:~#
 
Now I'd like to do
ControlSend($hWindow_Putty, '', '', 'perl -w /some/dir/script.pl{ENTER}')
 
If I'd do this on my on with Putty I'd now see something like:
 
Using username "root".
Linux COMPUTERNAME 2.6.31-22-generic-pae #63-Ubuntu SMP Wed Aug 18 23:57:18 UTC 2010 i686
 
To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
 
  System information as of Mo 13. Jan 15:01:50 CET 2014
 
  System load:  0.0               Processes:           77
  Usage of /:   47.5% of 9.15GB   Users logged in:     1
  Memory usage: 9%                IP address for eth2: HOST
  Swap usage:   0%
 
  Graph this data and manage this system at https://landscape.canonical.com/
 
Last login: Mon Jan 13 14:58:43 2014 from XXX.X.X.XXX
root@COMPUTERNAME:~# perl -w some/dir/script.pl
some text written by the script.pl
some text written by the script.pl
some text written by the script.pl
root@COMPUTERNAME:~#
 
And that's what my problem is. I need to be able to check this output of the script like "some text written by the script.pl" because I may not execute a following statement if this one didn't succeed. In my thoughts the first step should show me what I got in the first code-box above, and the second output should be
perl -w some/dir/script.pl
some text written by the script.pl
some text written by the script.pl
some text written by the script.pl
root@COMPUTERNAME:~#
but I dont get this working ...
 
So I found many threads about Plink. I tried the whole thing with Plink...
 
Local $sData = ''
Local $iPID = Run('"C:\Program Files (x86)\Putty\plink.exe" -ssh root@HOST:22 -pw PASSWORD', @ScriptDir, @SW_SHOW, $STDERR_CHILD + $STDOUT_CHILD)
 
While True
    $sData &= StdoutRead($iPID)
    If @error Then ExitLoop
    Sleep(25)
WEnd
 
ConsoleWrite("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" & @CR & _
$sData & @CR & _
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" & @CR)
 I'm getting the following output:
Linux COMPUTERNAME 2.6.31-22-generic-pae #63-Ubuntu SMP Wed Aug 18 23:57:18 UTC 2010 i686
 
To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
 
  System information as of Mo 13. Jan 15:35:53 CET 2014
 
  System load:  0.0               Processes:           77
  Usage of /:   47.5% of 9.15GB   Users logged in:     1
  Memory usage: 9%                IP address for eth2: HOST
  Swap usage:   0%
 
  Graph this data and manage this system at https://landscape.canonical.com/
 
Last login: Mon Jan 13 15:23:36 2014 from MY_IP_ADRESS
 
In comparison to the Putty window-output I'm missing here the 
root@COMPUTERNAME:~#
line ... anyway, I don't get this Plink thing doing more then just connecting ... no more executions I'm getting done ...
 
I also tried something like:
#RequireAdmin
#include <Constants.au3>
 
Local $sData = ''
Local $iPID = ShellExecute(@ComSpec, '"C:\Program Files (x86)\Putty\plink.exe" -ssh root@HOST:22 -pw PASSWORD', @ScriptDir, '', @SW_SHOW)
 
Local $hWindow = WinWait('Administrator: C:\Windows\system32\cmd.exe', '', 5)
ConsoleWrite("WinWait: " & $hWindow & @CR)
If $hWindow = 0 Then Exit
ConsoleWrite("WinActivate: " & WinActivate('Administrator: C:\Windows\system32\cmd.exe') & @CR)
ConsoleWrite("WinActive: " & WinActive('Administrator: C:\Windows\system32\cmd.exe') & @CR)
 
Sleep(1000)
ConsoleWrite(ControlSend('Administrator: C:\Windows\system32\cmd.exe', '', '', '"C:\Program Files (x86)\Putty\plink.exe" -ssh root@HOST:22 -pw PASSWORD{ENTER}') & @CR)
 
;StdinWrite($iPID, '"C:\Program Files (x86)\Putty\plink.exe" -ssh root@HOST:22 -pw PASSWORD' & @CRLF)
;StdinWrite($iPID)
 
While True
    $sData &= StdoutRead($iPID)
    If @error Then ExitLoop
    Sleep(25)
WEnd
 
ConsoleWrite("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" & @CR & _
$sData & @CR & _
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" & @CR)
but unfortunately I dont get anything out of it ...
 
Maybe a last more example ... I found this on Stackoverflow (http://stackoverflow.com/questions/19206834/command-prompt-and-autoit-stdinwrite)
Thats my code after reading that article:
#include <Constants.au3>
 
Local $data
Local $pid = Run("C:\Windows\system32\cmd.exe",@SystemDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD)
StdinWrite($pid,"cd C:\users\username")
StdinWrite($pid,@CRLF)
;~ StdinWrite($pid)
 
Sleep(2000)
 
$data &= StdoutRead($pid)
ConsoleWrite("Debug:" & $data & @LF)
 
$data = ''
 
StdinWrite($pid,"cd C:\Program Files (x86)")
StdinWrite($pid,@CRLF)
StdinWrite($pid)
 
$data &= StdoutRead($pid)
ConsoleWrite("Debug:" & $data & @LF)
but the second output still empty...
 
Can you guys please help me out?
Thanks in advice.
Regards.
Edited by MikeWenzel

Share this post


Link to post
Share on other sites

May be like this ?

#Include <Constants.au3>

$sData = ''
$sStderrRead=''
$sStdoutRead=''
$iPid = Run ( '"' & @ProgramFilesDir & '\Putty\plink.exe" -ssh root@HOST:22 -pw PASSWORD', '', @SW_SHOW, $STDERR_CHILD + $STDOUT_CHILD)

While ProcessExists ( $iPid )
    $sStderrRead = StderrRead ( $iPid )
    If Not @error And $sStderrRead <> '' Then
;~      ConsoleWrite ( "! STDERR read : " & $sStderrRead & @Crlf )
    EndIf
    $sStdoutRead = StdoutRead ( $iPid )
    If Not @error And $sStdoutRead <> '' Then
        $sData &= $sStdoutRead
;~      ConsoleWrite ( "+ STDOUT read : " & $sStdoutRead & @Crlf )
    EndIf
;~   Sleep(25)
Wend

ConsoleWrite("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" & @CR & _
$sData & @CR & _
"~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" & @CR)

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

Sorry for not replying 2 days. I was pretty busy in school ...

Well your script is showing me exactly what I already got:

Linux COMPUTERNAME 2.6.31-22-generic-pae #63-Ubuntu SMP Wed Aug 18 23:57:18 UTC 2010 i686
 
To access official Ubuntu documentation, please visit:
http://help.ubuntu.com/
 
  System information as of Mo 13. Jan 15:35:53 CET 2014
 
  System load:  0.0               Processes:           77
  Usage of /:   47.5% of 9.15GB   Users logged in:     1
  Memory usage: 9%                IP address for eth2: HOST
  Swap usage:   0%
 
  Graph this data and manage this system at https://landscape.canonical.com/
 
Last login: Mon Jan 13 15:23:36 2014 from MY_IP_ADRESS

 

 

Besides the fact that I got no idea how I should be able to use plink like this because the window is closing (if not running from command-prompt) which means I cant execute statements after connection ...

Anyone any idea? :/

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Got this running....I'll post the solution later, first I have to get my application finished now ...

#Edit: Solution (Console.au3 helped me to get this done):

Local $iPID = Run('"C:\Program Files (x86)\Putty\plink.exe" -ssh -pw PASSWORD USER@HOST:PORT', "", @SW_HIDE, 7)
For $i = 0 To 3
Local $iTimeout = WinWait("C:\Program Files (x86)\Putty\plink.exe", "", 10)
If $iTimeout <> 0 Then
ExitLoop
Else
If $i = 3 Then Exit
EndIf
Next
 
$iRval = __PlinkExpect($iPID, "USER@")
If $iRval = 0 Then
MsgBox(48, "", 'PuTTY - Es konnte keine erfolgreiche verbindung aufgebaut werden.')
Exit
EndIf
StdinWrite($iPID, "WHATEVERUWANT" & @CR)
 
ProcessClose($iPID)
 
Func __PlinkExpect($iPlink_PID, $sPlink_Match, $iTimeout = 30000)
Local $sText
Local $iRval
Local $iTimer = TimerInit()
Local $iTimerDiff
 
While 1
$iTimerDiff = TimerDiff($iTimer)
If $iTimerDiff > $iTimeout Then Return 0
 
$sText = StdoutRead($iPlink_PID)
$iRval = StringRegExp($sText, $sPlink_Match)
If $iRval = 1 Then ExitLoop
 
Sleep(100)
Wend
 
Return 1
EndFunc
Func _PlinkExpect($iPlink_PID, $sPlink_Match)
Local $iRvl = 0
 
While 1
$iRval = __PlinkExpect($iPlink_PID, $sPlink_Match)
If $iRval = 1 Then ExitLoop
 
Sleep(10000)
WEnd
EndFunc
Edited by MikeWenzel

Share this post


Link to post
Share on other sites

Hi, 
Last 2 weeks I have searched many forums and i haven't found the answer for the question:
How to get all command output to Putty title?
Needed it for AutoIT to know when some jobs on a server is done and is it done right or wrong. Plink stdout and stdin wasn't working, I used many tweaks with wait delays and for some commands they worked and for others not. XSEL and XCLIP couldn't be installed on that server.

So here is the solution:
1. Get command output in a file.
2. Echo that file to title.

on putty client and suse server it looks like this:

ls /home | grep domagaja > logautoit.txt 
echo -e "\033]0\\;$(cat logautoit.txt)\\007\\c"

Hopefully someone will be able to use this. It won't work for all server types and putty client settings, of course, but the idea should work well.
Best
Jacek

Share this post


Link to post
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

  • Similar Content

    • rkr
      By rkr
      Hi, I have a software which has a 'run file'-ie; when i double click on that file, the input file of the software is run by the software. I wish to double click/execute this run file using autoit. how do i achieve this. i opened the software and it shows the input file and run file in same folder, i will put my autoitscript file too in same location. how do i simulate double clicking the run file (using its file name, say - abc.run ). I entered the following lines to make software window active - it became active, dont know how to go forward
      Winactivate("program title")
      winwaitactivate("program title")
      controlclick("program title","abc.run",1000,"primary",2) ; 1000 is ctrl id
    • tremolux66
      By tremolux66
      Initial Problem
      I've written several scripts with the following sequence:
      Execute a program using Run w/stdout+stderr captured Typically processes all the files in one directory tree to populate a second tree Execute a second program (also with Run) to monitor the products of the first program and Display a progress bar (percentage of output files complete) Also monitor the first program's process and exit when it terminates The script then calls ProcessWaitClose (no timeout) on the first program's process and Checks the first program's results Kills the monitor program if it hasn't already exited on its own. Sometimes, ProcessWaitClose returns 1 with @error = 0 and @extended = 0xCCCCCCCC (actually, 0xFFFFFFFFCCCCCCCC), which seems ambiguous: the documentation says that @error = non-zero and @extended = 0xCC... means an invalid PID (unclear what the return value is), and 1 is returned for non-existent processes (but no mention of @extended). The 1/0/0xCC... result seems to occur when the first program exits very quickly (with or without an error). Since the exit value is not available, the script scans the program's output and tries to determine whether it ran successfully. This has gotten complicated and unreliable.
      Partial Fix
      I've now implemented a much simpler approach that works for most cases:
      Modify the monitor program so that it ignores the other program's process (the monitor always gets killed by the script anyway) Execute the monitor program first using Run, then execute the processing program with RunWait When RunWait returns, the child process exit value is available, so the script can ignore its output (which isn't available anyway) If the monitor program is still running, kill it. Remaining Issue
      However, there are still a couple of cases where it's necessary to get both the exit value from the processing program and its output. Since RunWait doesn't capture stdout and stderr for the parent script, it's looking like I'll have to call RunWait and redirect the 2 streams to a temp file and then scan it. Also, to do the redirect, I think I'll have to use @ComSpec to execute the processing program, which adds an undesired layer.
      Does anybody have a better (cleaner) way to handle these cases?
    • e45678mail
      By e45678mail
      Hi~
      I have some question about how to enable the test mode via "Run" or "shellexecute" of command,
      was to tried :
      -----
      Run("bcdedit.exe /-set testsinging on", "C:\Windows\System32")
      and
      shellexecute("bcdedit.exe /-set testsinging on", "C:\Windows\System32")
      -----
      since this command must to run through administrator competence,
      have any method can accomplish it?
       
       
    • lganta
      By lganta
      Hello!
      I created some scripts for a simple farming bot a few years ago and they rely on ControlSend.
      A year ago I quit that game and then installed Windows 10 (was using windows 7).
      Recently I installed that game and tried running them again and they seem to work (I have some messages displayed on the screen with the state of the bot ), except for the ControlSend part (which obviously is crucial).
      I started debugging the scripts so I created a basic script that makes use of Send. I tested this with Notepad in focus and works just fine and then with my game window in focus and it didn't work (it's supposed to write that text in an input box from the game).
      #include <MsgBoxConstants.au3> Sleep(3000); Send("some text"); MsgBox($MB_OK, "Notification", "Control was sent!");  
      Is there a way for the creators of the game to create some kind of security system against this? Or something happens because I updated to Windows 10?
      Is there something I'm missing?
      Thank you!
    • Jason86
      By Jason86
      Hi,
      I would like to automate Putty commands whereby it will select my saved telnet session (so open Putty Configuration and select session) and afterwards it will open the Putty-prompt and will do next commands:
      <Enter>
      ACCESS <Enter>
      'UserName' <Enter>
      SET Priv <Enter>
      'Password' <Enter>
      LOG PORT ALL <Enter>
      And close Putty
      Kind of new in AutoIT so all help is welcome !
       
      Thanks in advance,
      Regards,