23

Is there a way to redirect stdout and stderr for a batch file from inside it.

I'm imagining something like

set STDOUT=stdout.log
echo Some text
a.exe
b.exe
c.exe

Where both Some text, and the output of a.exe, b.exe and c.exe would go to stdout.log

Is this possible?

sashoalm
  • 75,001
  • 122
  • 434
  • 781

2 Answers2

35

It is more efficient to redirect once for the entire collection of commands than it is to redirect (with append) each individual command. It takes time to intialize the redirection. It may not be noticable for a few redirected commands, but if done in a loop with many iterations, it can become quite significant.

One method is to enclose the entire block of redirected commands within parentheses and redirect outside the parentheses

>stdout.log 2>&1 (
  echo Some text
  a.exe
  b.exe
  c.exe
)

Another option is to put your commands in a subroutine and redirect the CALL

call :redirect >stdout.log 2>&1
exit /b

:redirect
echo Some text
a.exe
b.exe
c.exe
exit /b
dbenham
  • 127,446
  • 28
  • 251
  • 390
  • What is the way to put the log filename into a variable? – domih May 29 '17 at 12:13
  • Awesome trick! Note that with the first method using parentheses, closing parentheses *within* the outer block must be escaped with a caret ^. And if you pipe the output, each closing parenthesis requires three carets--see https://stackoverflow.com/a/12976840/550712. – Mark Berry Feb 05 '20 at 18:49
8

Yes, you need to redirect and append stdout to your file (1>> %STDOUT%) and connect stderr to stdout (2>&1):

set STDOUT=stdout.log
echo Some text 1>> %STDOUT% 2>&1
a.exe 1>> %STDOUT% 2>&1
b.exe 1>> %STDOUT% 2>&1
c.exe 1>> %STDOUT% 2>&1

@EitanT correctly noted that your question doesn't necessarily imply writing both stderr and stdout into the same file. So for completeness, here's a version writing into separated files:

set STDOUT=stdout.log
set STDERR=stderr.log
echo Some text 1>> %STDOUT% 2>> %STDERR%
a.exe 1>> %STDOUT% 2>> %STDERR%
b.exe 1>> %STDOUT% 2>> %STDERR%
c.exe 1>> %STDOUT% 2>> %STDERR%
zb226
  • 9,586
  • 6
  • 49
  • 79
  • 1
    +1: You don't have to redirect `stderr` to `stdout`... if you want you can redirect them to separate logs. – Eitan T Nov 15 '12 at 14:17
  • 1
    Of course you don't have to, but I thought he wanted to do exactly that: _...to redirect stdout **and** stderr..._ – zb226 Nov 15 '12 at 14:20
  • Yes, redirect both of them but not necessarily to the same location. Never mind, I'm just nitpicking... – Eitan T Nov 15 '12 at 14:21