Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Windows batch file: Pipe destroys my return code

Tags:

batch-file

cmd

is it possible to return the errorlevel also if I pipe the output of a script into a logfile:

test1.bat:

 call test2.bat 2>&1 | tee log.txt
 echo ERRORLEVEL: %ERRORLEVEL%

test2.bat:

 exit /B 1

Output when calling test1.bat:

 ERRORLEVEL: 0

The errorlevel is always 0.

The problem is, I want to call another script inside my script where the output should be redirected synchronously with the output shown in the command line, therefore a simple > is not enough for me. I tried several ideas, but result is that the pipe always seems to destroy the given error-level... :(

Can you give me any further suggestions?

Thanks in advance... :)


Thanks for your answer... Unfortunately this does not work as well... :( See what I tried:

test1.bat:

 echo off
 set VAR1=" "
 echo VAR1 before test2: %VAR1%
 call test2.bat 2>&1 | tee log.txt
 echo VAR1 after test2: %VAR1%

test2:

 @echo off
 set VAR1=ERROR
 echo VAR1 in test2: %VAR1%
 exit /B 1

Output when calling test1.bat:

 VAR1 before test2: " "
 VAR1 in test2: ERROR
 VAR1 after test2: " "

As an other solution I tried to save "ERRORVALUE: 1" into the logfile in case there is an error. In the mainscript I wanted to parse the log looking for this string. Unfortunately saving the find-result to an environment variable does not work as well, I did as follows:

FOR /F "tokens=1 delims=" %%A in ('type %logDir%\03_applySqls.log | find /c "ERRORVALUE: 1"') do SET val=%%A

Error I get:

"|" ist syntaktisch an dieser Stelle nicht verarbeitbar.

So how can I at least parse my logfile and in case the string is found in the log I can return the value as an errorlevel?

like image 911
murxx Avatar asked May 18 '10 13:05

murxx


People also ask

What does pipe mean in batch file?

The pipe operator (|) takes the output (by default, STDOUT) of one command and directs it into the input (by default, STDIN) of another command. For example, the following command sorts the contents of the directory C:\ dir C:\ | sort.

Why is %% used in batch file?

Outputs the content of temp variable even if run from a batch file. Use of the percent sign in a batch to access environment variables and passed arguments needs no escaping.

What is %% R in batch command?

/r - iterate through the folder and all subfolders, i.e. recursively. %%I - placeholder for a path/filename. The above command simply lists all files in the current folder and all subfolders.

How do I change the return code in a batch file?

It is common to use the command EXIT /B %ERRORLEVEL% at the end of the batch file to return the error codes from the batch file. EXIT /B at the end of the batch file will stop execution of a batch file. Use EXIT /B < exitcodes > at the end of the batch file to return custom return codes.


3 Answers

Nasty. I can only suggest a wrapper batch file that squirrels away the exit code of a passed command. An environment variable won't quite cut the mustard here. I suggest writing it to an unused fd, say 4.

wr.cmd:

call %*
echo %errorlevel% >&4
echo Some error message >&2

This is slightly tricky as fd 4 must be open when wr.cmd is called. For testing sake, here I echo Some error message to stderr to show that such text remains separate from the error level.

test1.bat:

call wr test2.bat 4>fail.txt 2>&1 | tee log.txt
set /p fail= <fail.txt
echo FAIL: %fail%
like image 54
bobbogo Avatar answered Oct 12 '22 22:10

bobbogo


Well, the problem is that tee exits after your batch file and therefore its own exit code overwrites the one of the batch file.

There's (to my knowledge) not much you can do about that, except use another error handling mechanism. You can use an environment variable to store the exit code of your batch. tee won't touch that.

like image 32
Joey Avatar answered Oct 12 '22 23:10

Joey


How about:

FOR /F "tokens=1 delims=" %%A in ('find /c "ERRORVALUE: 1" %logDir%\03_applySqls.log') do SET val=%%A
like image 41
MJZ Avatar answered Oct 12 '22 22:10

MJZ