Is there a way to redirect stderror to stdout for the duration of a script in Windows?
-
03-07-2019 - |
Question
As a long time UNIX shell scripter / release engineer coming into the Windows environment full time with my latest job, there are some things I inevitably miss.
One of them is my trusty old 'exec 2>&1' which in the Bourne shell permently knots together stderr and stdout for the duration of the script, so that logging will capture everything good and bad.
I realize you can append 2>foo.log to the end of every command line invocation, but I'm wondering if there's a better way.
Is there any equivalent in the Windows environment? We're using both .BAT file scripts and Perl scripts here (Mostly for build automation but also some other things) and I'd dearly love to know if this is possible at all.
Solution
You can nest the .BAT that does the real work inside a .BAT that redirects the streams for logging.
Something like
rem log.bat cmd /c work.bat 1>>logfile.log 2>&1
rem work.bat make all perl cleanups.pl
might do the trick. You might be able to use CALL instead of directly invoking a second CMD.EXE, I haven't checked. If that does work, then the solution can be self contained: just call yourself with an extra argument to indicate the logging is in effect and with the streams redirected.
OTHER TIPS
In Perl you can do
open STDERR, '>&STDOUT' or die "Can't dup STDOUT";
to redirect the STDERR output of the script to STDOUT. See the open
documentation for more info. I wouldn't expect this to effect the output of system calls, i.e. system
or backticks.
You can apply redirection to command blocks as well as single commands
(
echo 1
dir
echo 2
) >somefile.txt
Note that it is impossible to use labels and goto inside of command blocks, though.
Read this KB article from MS. Sample taken from the said article:
You can print the errors and standard output to a single file by using the "&1" command to redirect the output for STDERR to STDOUT and then sending the output from STDOUT to a file:
dir file.xxx 1> output.msg 2>&1
The 2>&1
thing seems to be working for me for scripts:
testcmd.cmd > stdboth.txt 2>&1
What exactly are you doing and what are you expecting when you're doing it?
:log_me
@if "%~1" NEQ "*" ("%~nx0" * >> "%~n0.log" 2>&1)
:script
echo this is success
echo this is error>&2
And, if your batch script has command line parameters:
:log_me
@call :script %* >> "%~n0.log" 2>&1
exit /b
:script
echo this is success
echo this is error>&2