Redirect stderr in windows

Redirect batch stderr to file

I have a batch file that executes a java application. I’m trying to modify it so that whenever an exception occurs, it’ll write the STDERR out to a file.

It looks something like this:

Is there a way I can write the arguments %1 and %2 to the log.txt file as well? I don’t want to write it to the log file everytime this batch file gets called, only when an exception occurs.

I tried searching for a way to redirect STDERR into a variable, but I couldn’t figure it out. Ideally I’d like the log file to look something like:

6 Answers 6

Something like this might work:

javastart.cmd

I am not a java programmer myself, I cannot test this output/situation but:

1: %* means every parameters, from 1st to last (even %12 although it’s not directly available.. ) whatever the formating. Might be better to use this than delimit those. In the even of bad spacing/quoting, you would have the full parameters too. I added a line in the log, to show the full line then the parameters. You can see where the problem was if it’s a matter of bad arguments.

2: sending the stdout to null (^>nul) will only keep the stderr output, set into %%e

3: Whatever is in the do part will only happen is the for test statement actually has anything as an output, i.e. if %%e is set.

With those being said, you have to test the script and see if the exception is actually sent to stderr or, like some other softwares, to stdout even if an error occured.

I hope this helps.

The only working solution I see would be to redirect stderr to a temporary file

and afterwards looking whether something has been written to the file and writing to the log in that case.

If the batches aren’t run in sequence but rather simultaneously you need to find something to uniquify the temp variable:

This will avoid clashes between multiple running batches. However, you are currently not using anything to lock writing to your log file and things may appear out of place when other things get written to it (with other batches you might get interleaving in the echo and type commands or, when you’re redirecting output of java to that file as well, then it may get mixed up with regular output of the java program:

C: how to redirect stderr from System-command to stdout or file?

The shell command $ avrdude -c usbtiny outputs text to stderr. I cannot read it with commmands such as head-less-more cos it is not stdout. I want the text to stdout or to a file. How can I do it in C? I have tried to solve the problem by my last question but still unsolved.

4 Answers 4

I’ve not tried something like this in OpenBSD, but in at least a few *nix-like systems, you can do this using dup2 .

Читайте также:  Virtualbox linux init d

The normal way would be something like:

This directs what would normally go to stderr to go to stdout instead. If you’d prefer to direct it to a file, you could do something like:

The following uses the POSIX function to duplicate the standard output file number into the standard error file number. Duplicating stderr to stdout is given in the POSIX page for dup2 as an example usage of the function.

I need to somehow block the command in C so I can get its stderr

Start by reading man fork , man exec on how to start a child process. Look into man 7 signal , man sigaction and man wait for how to reap the child.

Finally, the man dup2 .

Untested code to exemplify:

Using dup2() we replace stderr (which is fd 2) of the child with a writing end of a pipe. pipe() is called before fork(). After fork we also have to close all hanging ends of the pipe so that the reading in parent process would actually receive EOF.

Probably there is a simpler solution using stdio, but I’m not aware of it. Since popen() runs the command via shell, probably one can tell it to redirect stderr to stdout (and send stdout to /dev/null). Never tried that.

One can also use mktemp() ( man 3 mktemp ) to create a temp file name, compose command for system() to redirect stderr of the command to the temp file and after system() returns read the temp file.

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:

Читайте также:  Приложение для сканирования документов windows 10 abbyy finereader

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 C++: How can I redirect stderr for calls to fprintf?

I am wrapping existing C++ code from a BSD project in our own custom wrapper and I want to integrate it to our code with as few changes as possible. This code uses fprintf to print to stderr in order to log / report errors.

I want to redirect this to an alternative place within the same process. On Unix I have done this with a socketpair and a thread : one end of the socket is where I send stderr (via a call to dup2 ) and the other end is monitored in a thread, where I can then process the output.

This does not work on Windows though because a socket is not the same as a file handle.

All documents I have found on the web show how to redirect output from a child process, which is not what I want. How can I redirect stderr within the same process getting a callback of some sort when output is written? (and before you say so, I’ve tried SetStdHandle but cannot find any way to make this work).

3 Answers 3

You can use a similar technique on Windows, you just need to use different words for the same concepts. 🙂 This article: http://msdn.microsoft.com/en-us/library/ms682499.aspx uses a win32 pipe to handle I/O from another process, you just have to do the same thing with threads within the same process. Of course, in your case all output to stderr from anywhere in the process will be redirected to your consumer.

Actually, other pieces of the puzzle you may need are _fdopen and _open_osfhandle. In fact, here’s a related example from some code I released years ago:

In this case, the main process was a GUI process which doesn’t start with stdio handles at all. It opens a console, then shoves the right handles into stdout and stdin so the debug() function (which was designed as a stdio interactive function) can interact with the newly created console. You should be able to open some pipes and do the same sort of thing to redirect stderr.

You have to remember that what MSVCRT calls «OS handles» are not Win32 handles, but another layer of handles added just to confuse you. MSVCRT tries to emulate the Unix handle numbers where stdin = 0, stdout = 1, stderr = 2 and so on. Win32 handles are numbered differently and their values always happen to be a multiple of 4. Opening the pipe and getting all the handles configured properly will require getting your hands messy. Using the MSVCRT source code and a debugger is probably a requirement.

You mention that you don’t want to use a named pipe for internal use; it’s probably worth poining out that the documentation for CreatePipe() states, «Anonymous pipes are implemented using a named pipe with a unique name. Therefore, you can often pass a handle to an anonymous pipe to a function that requires a handle to a named pipe.» So, I suggest that you just write a function that creates a similar pipe with the correct settings for async reading. I tend to use a GUID as a string (generated using CoCreateGUID() and StringFromIID() ) to give me a unique name and then create the server and client ends of the named pipe with the correct settings for overlapped I/O (more details on this, and code, here: http://www.lenholgate.com/blog/2008/02/process-management-using-jobs-on-windows.html).

Читайте также:  Pvs studio ��� linux

Once I have that I wire up some code that I have to read a file using overlapped I/O with an I/O Completion Port and, well, then I just get async notifications of the data as it arrives. However, I’ve got a fair amount of well tested library code in there that makes it all happen.

It’s probably possible to set up the named pipe and then just do an overlapped read with an event in your OVERLAPPED structure and check the event to see if data was available. I don’t have any code available that does that though.

Not the answer you’re looking for? Browse other questions tagged c++ windows redirect or ask your own question.

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.4.16.39093

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

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

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

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