1

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

dir file.xxx 1> output.msg 2>&1

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:

net use Z: \\server\share  |  TimeStampPipe.exe >> logfile.txt 

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

net use Z: \\server\share  1> 2>&1 TimeStampPipe.exe >> logfile.txt 

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

I tried this

net use Z: \\server\share  1| 2|&1 TimeStampPipe.exe >> logfile.txt 

and got & was unexpected at this time.

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

net use Z: \\server\share  1> tempfile.txt 2>&1
type tempfile.txt | TimeStampPipe.exe >> logfile.txt 
del tempfile.txt

Is there a more concise approach?

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

net use Z: \\server\share  | 2>&1 TimeStampPipe.exe >> logfile.txt 
net use Z: \\server\share  |  TimeStampPipe.exe 2>&1 >> logfile.txt 
net use Z: \\server\share  | TimeStampPipe.exe >> logfile.txt 2>&1

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

aschipfl
  • 28,946
  • 10
  • 45
  • 77
tim11g
  • 1,733
  • 4
  • 20
  • 33
  • 4
    If you think about it, StdOut doesn't normally need to be specifically redirected for piping, does it? So when you want to include StdErr, you'd just add it on its own. I'd therefore offer, just `2>&1`, _(i.e. send handle 2 to wherever handle 1 is going)_, instead of `1> 2>&1` – Compo Jun 07 '20 at 19:58
  • That makes sense, but doesn't work. See above for the formats I tried. In all cases, stderr goes to the screen (cmd window), not the pipe. – tim11g Jun 07 '20 at 20:52
  • 4
    Did you try `net use Z: \\server\share 2>&1 | TimeStampPipe.exe >>logfile.txt`? You want STDERR from the `net use` command, right? – SomethingDark Jun 07 '20 at 20:58
  • 2
    I'm sorry tim11g, I thought it was obvious, when I said redirection for piping, that the redirection was to be performed before the pipe! Please take a look at @SomethingDark's [comment above](https://stackoverflow.com/questions/62250716/windows-redirect-stderr-and-stdout-to-same-program-when-piping#comment110097393_62250716) to see what I meant. – Compo Jun 07 '20 at 21:58
  • Yes that's it. I was following the pattern from the articles of putting `2>&1` after the operative redirect, but clearly in the case if pipe it must come first. – tim11g Jun 09 '20 at 17:36

1 Answers1

1

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

net use Z: \\server\share 2>&1 | TimeStampPipe.exe >> logfile.txt

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

dir file.xxx 1> output.msg 2>&1

which is the same as:

dir file.xxx > output.msg 2>&1

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 (>):

net use Z: \\server\share 2>&1 | TimeStampPipe.exe >> logfile.txt
aschipfl
  • 28,946
  • 10
  • 45
  • 77