Capture and display STDOUT at the same time
Asked Answered
S

2

6

I have the following code to capture and process the Run command output. How do I modify it such that the Run command window displays output and at the same time the output gets logged? Replacing @SW_HIDE with @SW_SHOW (or the equivalent) just shows a blank command window.

Something similar to the linux tee command which logs to file while it prints STDOUT.

$CurrentPID = Run(@ComSpec & ' /c ' & $CurrentLogCmd, "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)

If Not ProcessWaitClose($CurrentPID,60) Then
    WriteLog("[Warning] Timed-out.Finding date in current hour raw log -" & $CurrentLogFileName)
    $F_LogWarningExist = 1
    Return $C_SUCCESS ; Take chances and proceed with parsing raw logs
EndIf

$CurrentOutput = StdoutRead($CurrentPID)
Sabatier answered 9/5, 2013 at 14:12 Comment(0)
G
4
ConsoleWrite(_getDOSOutput('ipconfig /all') & @CRLF)

Func _getDOSOutput($command)
    Local $text = '', $Pid = Run('"' & @ComSpec & '" /c ' & $command, '', @SW_HIDE, 2 + 4)
    While 1
            $text &= StdoutRead($Pid, False, False)
            If @error Then ExitLoop
            Sleep(10)
    WEnd
    Return StringStripWS($text, 7)
EndFunc   ;==>_getDOSOutput

Maybe this helps you out.

Gorden answered 16/5, 2013 at 7:13 Comment(3)
I actually need the text to be printed on the window in addtion to redirection... can both be possible at the same time?Sabatier
What do you mean by that?Gorden
I want the text to be printed on screen as well redirected so that autoit can read and parse. basically when I am on the monitor i want to see whats happening instantly (with scripts progress) rather than wait at the end for the autoit to throw an error if at all any!Sabatier
M
2

Something similar to the linux tee command which logs to file while it prints STDOUT.

Redirecting STDOUT makes receiving party (the script) responsible for display and logging. As per documentation:

StdoutRead() does not block, it will return immediately. In order to get all data, it must be called in a loop.

Example:

#AutoIt3Wrapper_Change2CUI=Y

#include <Constants.au3>
#include <MsgBoxConstants.au3>

Global Enum  $EXIT_OK, _
             $EXIT_NOCOMPILE, _
             $EXIT_ABORT

Global Const $g_sPromptError  = 'Compile this script and run resulting executable instead.', _
             $g_sPromptInput  = 'Enter a command:', _
             $g_sInputDefault = 'ping localhost -n 10'

Global       $g_sCMD = '', _
             $g_sSTD = ''

Main()

Func Main()

    If Not @Compiled Then

        MsgBox($MB_OK + $MB_ICONERROR, @ScriptName, $g_sPromptError)
        Exit $EXIT_NOCOMPILE

    EndIf

    $g_sCMD = InputBox(@ScriptName, $g_sPromptInput, $g_sInputDefault)
    If @error Then Exit $EXIT_ABORT

    $g_sSTD = _getCmdStd($g_sCMD)
    MsgBox($MB_OK + $MB_ICONINFORMATION, $g_sCMD, $g_sSTD)

    Exit $EXIT_OK
EndFunc

Func _getCmdStd(Const $sCMD, Const $sDir = '', Const $iType = $STDERR_MERGED, Const $bShow = False, Const $iDelay = 100)
    Local       $sTMP = ''
    Local       $sSTD = ''
    Local       $sCOM = @ComSpec & ' /c ' & $sCMD
    Local Const $iWin = $bShow ? @SW_SHOW : @SW_HIDE
    Local Const $iPID = Run($sCOM, $sDir, $iWin, $iType)

    While True

        $sTMP = StdoutRead($iPID, False, False)

        If @error Then

            ExitLoop 1

        ElseIf $sTMP Then

            $sTMP  = StringReplace($sTMP, @CR & @CR, '')
            $sSTD &= $sTMP

            ConsoleWrite($sTMP)

        EndIf

        Sleep($iDelay)

    WEnd

    Return SetError(@error, @extended, $sSTD)
EndFunc

Returns STDOUT (and STDERR) after execution completes, while writing to console during execution. Replace MsgBox() as required (logging function).

Mcguinness answered 27/12, 2014 at 0:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.