Redirecting stderr in windows

Redirect Windows cmd stdout and stderr to a single file

I’m trying to redirect all output (stdout + stderr) of a DOS command to a single file:

Is it possible, or should I just redirect to two separate files?

7 Answers 7

The syntax 2>&1 will redirect 2 (stderr) to 1 (stdout). You can also hide messages by redirecting to NUL , more explanation and examples on MSDN.

Anders Lindahl’s answer is correct, but it should be noted that if you are redirecting stdout to a file and want to redirect stderr as well then you MUST ensure that 2>&1 is specified AFTER the 1> redirect, otherwise it will not work.

Background info from MSKB

While the accepted answer to this question is correct, it really doesn’t do much to explain why it works, and since the syntax is not immediately clear I did a quick google to find out what was actually going on. In the hopes that this information is helpful to others, I’m posting it here.

From MSKB110930

Redirecting Error Messages from Command Prompt: STDERR/STDOUT

Summary

When redirecting output from an application using the ‘>’ symbol, error messages still print to the screen. This is because error messages are often sent to the Standard Error stream instead of the Standard Out stream.

Output from a console (Command Prompt) application or command is often sent to two separate streams. The regular output is sent to Standard Out (STDOUT) and the error messages are sent to Standard Error (STDERR). When you redirect console output using the «>» symbol, you are only redirecting STDOUT. In order to redirect STDERR you have to specify ‘2>’ for the redirection symbol. This selects the second output stream which is STDERR.

Example

The command dir file.xxx (where file.xxx does not exist) will display the following output:

If you redirect the output to the NUL device using dir file.xxx > nul , you will still see the error message part of the output, like this:

To redirect (only) the error message to NUL , use the following command:

Or, you can redirect the output to one place, and the errors to another.

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:

Windows Redirect STDERR and STDOUT to same program when piping

MSDN and this question give an example of redirecting Windows cmd stdout and stderr to a single file:

I’m looking to do the same when the STDERR and STDOUT are piped to another program. Here’s the usage without the STDERR redirects:

I want the STDERR and STDOUT of «net use» to be piped into TimeStampPipe.exe. I don’t care about STDERR from TimeStampPipe.exe. Where does the 2>&1 go to indicate that it applies to net use and not to TimeStampPipe.exe? I tried this

Читайте также:  Web сервер apache linux

and got 2>&1 was unexpected at this time.

and got & was unexpected at this time.

Is there a way to do this when piping? I could try something like:

Is there a more concise approach?

Edit: I tried the suggestion of @compo to use 2>&1 alone. I tried these three forms:

In each case, the stdout is correctly piped, but any stderr output from net use goes to the screen, not through the pipe.

1 Answer 1

As others already pointed out in comments you have to do this:

You already have got the right code to redirect both STDOUT and STDERR to a file:

which is the same as:

because output redirection ( > ) reads from STDOUT (handle 1 ) by default.

The expression 2>&1 defines that handle 2 (STDERR) is to be redirected to the destination that handle 1 (STDOUT) is currently (re-)directed to. The position of that expression is crucial.

For a pipe ( | ) you have to apply the same technique. Remember that a pipe redirects the output (at STDOUT, handle 1 ) of the left-side command into the input (at STDIN, handle 0 ) of the right-side command.

Now we want to redirect both STDOUT and STDERR of the left side into STDIN of the right side. Since nothing changes for the right side we keep it untouched. The left side however needs to be modified; STDOUT already goes where we want to, but STDERR does not yet, so we have to redirect it to the target of STDOUT, by using the same expression as for output redirection ( > ):

Is there a way to redirect ONLY stderr to stdout (not combine the two) so it can be piped to other programs?

I’m working in a Windows CMD.EXE environment and would like to change the output of stdout to match that of stderr so that I can pipe error messages to other programs without the intermediary of a file.

I’m aware of the 2>&1 notation, but that combines stdout and stderr into a single stream.

What I’m thinking of would be something like this:

But that combines stdout and stderr just like:

I realize that I could do.

But this does not have the flexibility and power of a program | find » » sort of notation. Doing this requires that program has finished with its output before that output can be processed.

2 Answers 2

CMD processes redirection from left to right. You want to first redirect 2 (stderr) to &1 (stdout), then redirect 1 (stdout) to something else. At this point stderr will still be redirected to the previous definition of stdout. The pipe will still work with the old definition of stdout (which now contains stderr).

If you don’t care about stdout then you can redirect to nul

If you want to capture stdout to a file then redirect to a file

If you still want to see stdout on the console, but you only want to pipe stderr to FIND, then you can redirect 1 to con:

Note that there is a subtle difference between the original definition of stdout and con:. For example, cls >con: does not clear the screen, it prints a funny character to the screen instead.

It is possible to truly swap stdout and stderr if you use a 3rd (initially unused) file handle. 1 and 3 will contain original definition of stderr, and 2 will contain original definition of stdout.

Actually there is an additional file handle defined every time a redirection is performed. The original definition is saved in the first available unused file handle. Assume there has not been any redirection prior to issuing the above command. 3>&2 does not save the original definition of 3 because 3 was not previously defined. But 2>&1 saves the original definition of stderr in 4 (3 has already been used), and 1>&2 saves the original definition of stdout in 5.

Читайте также:  Lenovo yoga duet 3 10igl5 linux

So technically, the explicit redirection of 3 is not needed to swap stderr and stdout

2>&1 saves stderr in 3 and 2 is redirected to &1 (stdout). 1>&3 saves stdout in 4 and 1 is redirected to &3 (stderr).

But the above will only work properly if you are positive that 3 has not already been defined prior to issuing the command. It is much safer to explicitly define 3 as in my prior code example.

Why doesn’t my stderr redirection end after command finishes? And how do I fix it?

In Windows, either in command line or a batch file, the command DIR 2>NUL: 3>&2 (you can replace DIR with anything, even if isn’t a file or a command) will make all errors from then on missing unless you write 2>CON: after every command. Why is CMD even doing this? And how do you get it back to normal without starting a new CMD process? DIR 2>CON: 3>&2 will only work for that command alone.

EDIT: This will work with files as well. DIR 2>TEXT.TXT 3>&2 Any errors after that will be appended to the file.

3 Answers 3

Here is a test script that reproduces the problem you are seeing.

And here is the output

stderr (stream 2) has been disabled «permanently», even for the parent CMD.EXE shell.

You can avoid the «permanent» aspect by doing your redirection in stages:

And here is the desired output:

I don’t really understand what is going on. But I have done some interesting experiments. Check out this thread: http://www.dostips.com/forum/viewtopic.php?f=3&t=2836&start=30

Addendum

As Erbert has discovered and shared in his comment, the fix is even easier if you just switch the order of the redirection — no need to stage it.

Update 2012-04-03 I believe I finally understand the mechanics of Windows CMD.EXE redirection. I have a working theory that fully accounts for all the weird behavior, including why reversing the order prevents the «permanent» redirection. It also explains Aacini’s observation that handle 3 appears to be connected to CON: (It isn’t, it is actually undefined as per Windows documentation).

The key points are:

1 — Whenever a handle (stream) is redirected, the original definition is transferred to the first available undefined handle. Successive redirections are always carried out from left to right.

2 — When the redirection is over, the original definitions are normally restored. But if there is a chain of redirections, then the restoration is only done 1 level deep. This is the source of the «permanent» redirection.

Edit 2014-12-19: Put another way, the restoration appears to be done using a queue structure (FIFO — First In First Out), when it should have been implemented as a stack (LIFO — Last In First Out).

3 — When CMD.EXE carries out the redirection, it saves the current definition in the undefined handle first, then it redirects the first handle. If the first handle is redirected to the originally undefined handle, then it is effectively redirected to its original definition! That is why echo hello 1>&3 outputs to the console.

The full theory and test cases are available in two consecutive posts at http://www.dostips.com/forum/viewtopic.php?p=14612#p14612.

I apologize for post this as an answer instead of a comment, but my «comment» is too large.

In the MS-DOS standard, all running programs have open these Standard Handles: 0-STDIN (keyboard), 1-STDOUT (screen), 2-STDERR (screen), 3-STDAUX (serial port) and 4-STDPRN (printer). Although Windows documentation clearly indicate that handles 3-9 are undefined, handle 3 have a special treatment by CMD.EXE. I have three reasons to think this:

Читайте также:  Macbook rdp to windows server

1- Handle 3 is connected to CON: device (keyboard for input, screen for output); handles 4-9 does not:

2- The strange behavior of handle 3 stated in the present topic, that was solved in two differents ways. I discovered that if handles 0, 1 or 2 are redirected with handle 3 (and possibly handles 4-9), the redirection of handles 0, 1 or 2 becomes «permanent»; this behaviour doesn’t happens if the handle 0, 1 or 2 are the last handle(s) in the list of redirections that include handle 3. This problem is entirely avoided if handles 0, 1 or 2 are redirected with handles 4-9 in any order, but not handle 3.

3- The results obtained with my TypeOfHandle.com program. This program is a pure MS-DOS executable file that check the handle given in its parameter and return via errorlevel a value of 3 if the handle is connected to the CONsole device, or a value of 128 if the handle is redirected to a disk file. These are the results:

Handles 3-9 behaves strange in other aspect:

Thinking In 16 Bits

Sunday, June 26, 2016

Redirecting stdout and stderr under Windows

Introduction

A console program (i.e. a program that is executed from the command line) can write its output on two separate streams: stdout and stderr. Theoretically stdout is used to display the program results and stderr is used to write error messages.

In a normal execution text written on both the stdout and the stderr isdisplayed on the console.

Lets try with an example. The following simplistic C# code writes a message on stdout and another message in stderr.

using System;
namespace TestStdout
<
class Program
<
static void Main(string[] args)
<
Console.Error.WriteLine(«STDERR message»);
Console.Out.WriteLine(«STDOUT message»);
>
>
>

If we execute this program on the windows command line we get

D:\test> TestStdout.exe
STDERR message
STDOUT message

Redirection

The redirection of stdout and stderr is well known by Linux users but strangely not so much popular for Windows users. However, it works (nearly) the same way with both operating systems

Redirect stdout to a file

To redirect the program output (stdout) to a file, use the operator >

D:\test> TestStdout.exe >out.txt
STDERR message

D:\test> type out.txt
STDOUT message

D:\test>

To get rid of stdout you may redirect it to a special file called NUL that throws away anything sent to it. (note that in Linux it is called /dev/null).

D:\test> TestStdout.exe >NUL
STDERR message

Redirect stderr to a file

To redirect the stderr you use the operator 2>

D:\test> TestStdout.exe 2>err.txt
STDOUT message

D:\test> type err.txt
STDERR message

You may also redirect stderr to NUL if you want to get rid of it

D:\test> TestStdout.exe 2>NUL
STDOUT message

D:\test>

Redirect both stdout and stderr to a file

You may combine > and 2> to redirect both stdout and stderr

D:\test> TestStdout.exe >out.txt 2>err.txt

D:\test>

It is also possible to redirect both stdout and stderr to the same file by using 2>&1 to first redirect stderr to stdout (&1 is in fact stdout) and redirect stdout to a file.

D:\test> TestStdout.exe >OutAndErr.txt 2>&1

D:\test> type OutAndErr.txt
STDERR message
STDOUT message

Redirecting to the clipboard

On Windows sytsems, it is possible to redirect directly to the clipboard instead of redirecting to a file (thank yo to Scott Hanselman for this trick ) by using | clip

Оцените статью