7

I have a command (let's call it command) that prints to standard out and will also set ERRORLEVEL based on the success or failure of the execution. I'd like to call command from a batch script that will process command's output, but only if command exited with an ERRORLEVEL of 0 (i.e. success). This would preferably be done without the need for a temporary file or checking the command's output to infer whether it was successful.

I'm able to capture the output of the command using a for statement, but I'm having trouble checking ERRORLEVEL when doing this. I've tried something like:

for /F %%A in ('command') do (
     REM The following check does not seem to work
     if ERRORLEVEL 1 goto error
     REM otherwise, do stuff with %%A
)

I've also tried using %errorlevel% and !errorlevel! (with setlocal enabledelayedexpansion), but neither worked.

3
  • Just out of curiosity, have you heard of PowerShell? Commented Jan 20, 2015 at 2:05
  • I have heard of it, but have yet to explore its power. In this particular case I'm trying to incorporate the above logic into an existing batch script, so I'd prefer not to have to rewrite everything as a PowerShell script unless I can use it as an interface between the batch script and the above logic. Commented Jan 20, 2015 at 2:13
  • Do you need to capture command output or just the exit code (errorlevel)? Have you tried simply putting this on line following command? IF %ERRORLEVEL% NEQ 0 goto error Commented Jan 20, 2015 at 3:05

2 Answers 2

2

Use a code like:

@echo off
"command.exe">"%TEMP%\CommandOutput.tmp"
if errorlevel 1 goto Failed

for /F "usebackq" %%A in ("%TEMP%\CommandOutput.tmp") do (
     REM Do stuff with %%A
     echo %%A
)
goto DelTempFile

:Failed
echo There was an error on executing command.

:DelTempFile
if exist "%TEMP%\CommandOutput.tmp" del "%TEMP%\CommandOutput.tmp"

This batch code first runs the command with redirecting standard output to a file in folder for temporary files. Next it evaluates the exit code of the command.

The output is processed with for if there was no error.

An appropriate error message is displayed instead on an error.

Finally the temporary file with the captured output is deleted before batch processing terminates.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the response, but I am looking for a solution that does not require the creation of a temporary file (if it's even possible).
2

The problem is that the command executed in the in clause of the for command runs in a separate cmd instance, and the exit code from that instance is not propagated to the code inside the do clause.

If you need a for command to process the output, and need the errorlevel of the spawned command inside the do clause, you will need to separate the both and generate a temporary file.

The answer from Mofi is probably the fastest, easiest and more direct solution without having to involve a external scripting engine/powershell.

For a solution with most of the code wrapped inside the in clause:

@echo off
    setlocal enableextensions disabledelayedexpansion

    rem Some commands for testing - command/uncomment as needed
    set "command=findstr 2> nul"  
    rem set "command=ping -n 1 localhost"
    rem set "command=ping -n 1 localhost | find "TTL^^^=" "

    set "el="
    for /f "delims=" %%a in ('
        cmd /v /q /c "set "t^=%temp%\%~nx0.%random%"&(>"!t!" (%command%)&echo(!errorlevel!&type "!t!"&del /q "!t!")"
    ') do if not defined el ( 
        rem The first line in the output is the exit code of the executed command
        set "el=%%a" & if %%a gtr 0 goto failed 
    ) else (
        rem Process the output of the command
        echo(%%a
    ) 
    exit /b

:failed
    echo failed with errorlevel %el%
    goto :eof

The basic idea is to get the errorlevel as the first line in the output of the executed command so we can check it and decide if more processing is needed.

note: this will not avoid having to load all the output into memory. The for /f loads all the data before starting to execute the code in the do clause, and is more efficient when the data is being retrieved from a file that from a command execution (one of the reasons that makes the answer from Mofi faster)

2 Comments

I really don't like to accept this, there has to be a better way ...
The better way is called PowerShell

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.