Jump to content
Yaerox

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

Recommended Posts

Yaerox
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
wakillon

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
Yaerox

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
Yaerox

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
domagaj

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

    • rudi
      By rudi
      Hello,
      for a script to display PDF files I'd like to simply use the default program for PDF files, so I used "ShellExecute(<pdf-file-full-path>)" to open these files.
       
      The result for *SOME* of the workstations is, that the Adobe Reader starts up with asking for its language. (English/German). When starting AcroRd32.exe through "ShellExecute()", this "choose your language" dialog is showing up *ALWAYS*.
       
      Just to have mentioned it: Process Explorer is presenting this command line, it looks the same for both, PCs with and without that question "Choose Language? [English|German]"
      "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" --channel=4680.0.860715181 --type=renderer "\\pc0009\Y_DRV_H\Daten\TIF\08\32\G000110832_Freigegeben.idw.pdf"  
      The next approach I thought of was to use Foxit Portable (instead of Acrord32.exe), started from a Network Drive, but it's starting up ugly slowly...
      So I tried to "Run()" instead to "ShellExecute()" the Adobe Reader. Now the result looks more stange, the "select your language" dialog shows up every now and then, but not always for the Win7 installations affected.
       
      If I place a "msgbox()" just in front of the "run()" command, it seems never to show this "select your language" dialog.
      If I take out this MsgBox() the "select your language" dialog shows up sometimes.
      When I "ClipPut()" the run command prior the "Run()" and paste that one to a CMD box, then it seems to *NEVER* happen, that this "select your language" dialog shows up.
       
      "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe" "\\pc0009\Y_DRV_H\Daten\TIF\08\32\G000110832_Freigegeben.idw.pdf" $AcroRead='"C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe"' $PDF='"Y:\Temp\DRV_H\Daten\TIF\33\85\153385_Freigegeben.dwg.pdf"' MsgBox(0,"Values",$AcroRead & @CRLF & $PDF,1) $MyCommand=$AcroRead & " " & $PDF ClipPut($MyCommand) Run($MyCommand)  
      It looks like, that this "--channel=... --type=renderer" parameters are always fact for the AcroRd32.exe instance, that is opening the PDF to be displayed. The Instance opening the "PDF Display GUI" seems to always be a child process of another AcroRd32.exe process.
       
      Any clue, what's going on "backstage" here? How to avoid this "Choose your language" dialog? Or maybe someone can mention a different "portable" PDF viewer, I could use for this purpose?  
      Any suggestions appreciated, regards, Rudi.
    • ModemJunki
      By ModemJunki
      OK, the odd stuff seems to happen to me. Not sure if this belongs here or in the deployment forum.
      The Question: Why would the console output results from a command-line tool need to know the working dir on one system but not the other?
      Though in the end I solved the issue I still am not understanding why StdoutRead seems to behave differently as I describe below.
      Preamble: Windows 10 image deployment to two different HP workstation hardware platforms. After deployment set up some disk space using Intel RAID. I script the Intel RSTe client (Intel® Rapid Storage Technology enterprise). Same version of the RSTe client and same storage controller hardware (Intel C600+/C220+ series chipset SATA RAID controller). The only difference is in the driver - one system has 4.2.0.1136 and the other has 5.2.0.1194, but even after I update the older driver the anomaly persists. There are of course other differences - the older system has different CPUs (Xeon E5-2620 vs Xeon Silver 4108), different chipsets, different SMBIOS, etc..). Both have Nvidia Quadro cards with driver 385.90, but the older has 3x P2000 cards and the newer has 3x Quadro M4000 and a Quadro K1200.
      To script RAID creation and maintenance I have a function that uses StdoutRead with Intels command line client tool "rstcli64.exe".
      On the older system, the below call to StdoutRead fails. On the newer system, it works. This only started happening on the older hardware when I updated the Windows version 1607 image to build 14393.2189 (but the Windows image used is the same for both hardware targets).
      $s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) But if I change it to use @ScriptDir as the working dir, it works for both systems.
      $s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)  The code below is the one that works on both systems (hint: the comment " ; this only deals with one device" is because I've no hardware with more than one ATAPI device to test with).
      $s_RSTExe = ".\rstcli64.exe" ; for production (compiled executable) ; #FUNCTION# ==================================================================================================================== ; Name ..........: GetDiskInfoFromRSTE() ; Description ...: Queries for hard disks attached to the controller ; Syntax ........: GetDiskInfoFromRSTE() ; Parameters ....: None ; Return value...: An array of attached hard disk datas from the RST command line tool without ATAPI devices such as optical drives ; =============================================================================================================================== Func _GetDiskInfoFromRSTE() Local $s_RSTcmd = $s_RSTExe & " -I -d" Local $s_DoRST, $a_RSTDisksTemp, $s_rawdata, $numDISK = 0 If $Debug <> 0 Then ConsoleWrite("Get disk info: " & $s_RSTcmd & @CRLF) ; useful during dev but cannot be used if #requireadmin $s_DoRST = Run(@ComSpec & " /c " & $s_RSTcmd, @ScriptDir, @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) ProcessWaitClose($s_DoRST) $s_rawdata = StdoutRead($s_DoRST) $a_RSTDisksTemp = StringSplit($s_rawdata, @CRLF) For $i = $a_RSTDisksTemp[0] To 1 Step -1 ; since we are deleting items, we have to go backwards through the array If $a_RSTDisksTemp[$i] = "" Or $a_RSTDisksTemp[$i] = "--DISK INFORMATION--" Then _ArrayDelete($a_RSTDisksTemp, $i) EndIf Next $a_RSTDisksTemp[0] = UBound($a_RSTDisksTemp) If IsArray($a_RSTDisksTemp) Then For $j = $a_RSTDisksTemp[0] - 1 To 1 Step -1 ; we need to remove the ATAPI device(s), since we delete we have to step through in reverse If StringInStr($a_RSTDisksTemp[$j], "Disk Type: SATA") Then $numDISK = $numDISK + 1 EndIf Next For $j = $a_RSTDisksTemp[0] - 1 To 1 Step -1 ; we need to remove the ATAPI device(s), since we delete we have to step through in reverse If StringInStr($a_RSTDisksTemp[$j], "ATAPI") Then ; we have to delete the ID entry BEFORE and AFTER the ATAPI entry to remove the ATAPI device (always delete from the bottom up!). _ArrayDelete($a_RSTDisksTemp, $j + 1) ; delete entry below _ArrayDelete($a_RSTDisksTemp, $j) ; delete entry _ArrayDelete($a_RSTDisksTemp, $j - 1) ; delete entry above ExitLoop ; this only deals with one device. If there were more we would need to capture all ATAPI device ID locations into another array then delete the original array entries based on the index numbers in the new array. EndIf Next $a_RSTDisksTemp[0] = UBound($a_RSTDisksTemp) If $a_RSTDisksTemp[0] <> 1 Then If $Debug <> 0 Then ConsoleWrite("Found " & $numDISK & " disk(s) attached to controller." & @CRLF) _infoLog("_GetDiskInfoFromRSTE() found " & $numDISK & " disk(s) attached to controller.", $msgSource) Else If $Debug <> 0 Then ConsoleWrite("No disks found to be attached to controller." & @CRLF) _infoLog("No disks found to be attached to controller.", $msgSource) EndIf Else If $Debug <> 0 Then ConsoleWrite("Unable to query RAID controller. Check hardware and version of RST client software." & @CRLF) _errorLog("Unable to query RAID controller. Check hardware.", $msgSource) Exit EndIf Return $a_RSTDisksTemp EndFunc ;==>_GetDiskInfoFromRSTE  
    • PoojaKrishna
      By PoojaKrishna
      Hi friends,
      I'm trying to send SHIFTDOWN, to keep the Shift key pressed until I close the program or releases the key.
      Send ( "{SHIFTDOWN}") sleep(100) $text = InputBox("Shift key down", "Shift key is down. Type something: ") $ret = Msgbox(0,"", "Press and release shift key manually and select [Ok] to continue") $text = InputBox("Shift key up", "Shift key is released manually, now type something: ") Send ( "{SHIFTDOWN}") sleep(100) $text = InputBox("Shift key down Agin", "Shift key is pressed again, now type something: ") In the above program sequence,
      1. Send SHIFTDOWN from program, Works as we type in the text are in Capital letters
      2. Manually presses and releases the SHIFT button. SHIFT key is released as when we type, text is in small letters only.
      3. Again send SHIFTDOWN from program, but not working. When we type the letters are in small letters.
       
      If we send a SHIFTUP  before  sending the SHIFTDOWN again, then it is working correctly and the text appears in capital letters only. Can any one explain why this happens?
      Send ( "{SHIFTDOWN}") sleep(100) $text = InputBox("Shift key down", "Shift key is down. Type something: ") $ret = Msgbox(0,"", "Press and release shift key and select [Ok] to continue") $text = InputBox("Shift key up", "Shift key is released manually, now type something: ") Send ( "{SHIFTUP}") sleep(100) Send ( "{SHIFTDOWN}") sleep(100) $text = InputBox("Shift key down", "Shift key is pressed, now type something: ")  
      Thank you.
    • TheDcoder
      By TheDcoder
      Hello everyone, long time since I made a post in the H&S sub-forum
      I am working on a project where in a situation I would have to hold down an arrow key and release it in another statement/command, however when I wrote the code it isn't working exactly like I thought it would. Here is an example:
      Send("{UP down}") Sleep(10000) Send("{UP up}") This should hold the up arrow key for 10 seconds before releasing it again, but when I run this code the cursor in SciTE moves up only once
      If I hold the up arrow manually for 10 seconds it "repeats" and the cursor moves up several times until I release the key... Is this a known limitation of Send? Is there any other way I can accomplish this?
      Thanks for all the help and feedback in advance! TD
    • SkysLastChance
      By SkysLastChance
      Run("notepad.exe") GLOBAL $One = ('Line1' & _ 'Line2' & _ 'Line3' & _ 'Line4' & _ 'Line5') ClipPut($One) $Notepad = WinWait("[CLASS:Notepad]", "", 10) ControlSend("Untitled - Notepad", "", "", ("^v")) Instead of having this paste as Line1Line2Line3Line4Line5
      How can I make it paste it into notepad as (without double spacing.)
      Line1
      Line2
      Line3
      Line4
      Line5
×