Linux G++ Compiler Redirect Stderr and Stdout Creates Empty File

linux g++ compiler redirect stderr and stdout creates empty file

One of your comments betrays that you are not using bash. You're using csh or tcsh. In that case, you can redirect all output (including standard error) like this:


g++ -c Algorithms.cpp >& output

For more csh redirection syntax, I have a useful link bookmarked. Note that csh redirection syntax is not as fluent as bash syntax. You can do more in bash than you can in csh.

Redirect the output of g++ compiler to a file?

For csh type of shells, do:

g++ test.cpp >& xx

Unable to redirect error to /dev/null in gnu make

You are redirecting the output of the grep command. You want to redirect the output of the icc command.

COMPILER_IN_PATH := $(shell icc -dumpversion 2>/dev/null | grep 2021.3.0)

What does 2&1 mean?

File descriptor 1 is the standard output (stdout).

File descriptor 2 is the standard error (stderr).

At first, 2>1 may look like a good way to redirect stderr to stdout. However, it will actually be interpreted as "redirect stderr to a file named 1".

& indicates that what follows and precedes is a file descriptor, and not a filename. Thus, we use 2>&1. Consider >& to be a redirect merger operator.

How to redirect gcc errors to a file in Unix?

In tcsh you don't use 2> to redirect stderr, you use >& that will redirect both stdout and stderr. If you want to redirect them separately, have a look at this quick guide.

In linux, stdin, stdout, stderr means open file descriptor?

Here is a small C program fd.c that uses stdout and stderr to print a message to the console.

#include <stdio.h>

int main(int argc, char*argv[])
{
fprintf(stdout,"message for stdout\n");
/* fflush(stdout); */
fprintf(stderr,"message for stderr\n");
/* fflush(stderr); */

return 0;
}

To compile: gcc -o fd fd.c

Open a terminal and test run:

./fd
./fd > /tmp/output.log
./fd > /tmp/stdout.log 2>/tmp/stderr.log
./fd > /tmp/all.log 2>&1

Examine each output file. If they look out of sequence, uncomment the fflush statements.

Nothing happens to their relations, they remain as they are as before. The 0,1,2 descriptors are always open by default.

How can I redirect STDERR to STDOUT, but ignore the original STDOUT?

What does not work:

The reason the last command you quoted:

cmd 1>/dev/null 2>&1 | grep pattern

does not work, stems from a confusion on the order in which redirection works. You expected the last quoted redirection to be applied to the ones before it on every output, so that output the original standard output file descriptor (1) will go to /dev/null, and output to the standard error file descriptor (2) will go to the original standard output.

However, this is not how shell redirection works. Each redirection causes the file descriptors to be "remapped" by closing the "source" and duplicating the "destination" into it (see the man pages of dup(2) and close(2)), in order. This means that in your command standard output is first replaced with /dev/null, and then standard error replaced with standard output, which is /dev/null already.

What works:

Therefore, to obtain the desired effect, you just need to reverse the redirections. Then you will have standard error go to standard output, and the original standard output go to /dev/null:

cmd 2>&1 >/dev/null | grep pattern

(note that the 1 before > is unnecessary - for output redirection standard output is the default)


Addendum: Charlie mentioned redirecting to &- to close a file descriptor. If using an interactive shell which supports that extension (bash and some other implementations do but not all and it is not standard), you can also do it like this:

cmd 2>&1 >&- | grep pattern

This may be better - it can save some time, because when the command tries to write to standard output the call to write may fail immediately without waiting for a context switch into the kernel and the driver handling /dev/null (depending on the system call implementation - some may catch this in the libc function, and some may also have special handling for /dev/null). If there is a lot of output that can be worthwhile, and it's faster to type.

This will mostly work because most programs do not care if they fail to write to standard output (who really checks the return value of printf?) and will not mind that standard output is closed. But some programs can bail out with a failure code if write fails - usually block processors, programs using some careful library for I/O or logging to stdandard output. So if it doesn't work remember that this is a likely cause and try /dev/null.

Redirecting stderr in csh

csh is significantly more limited than bash when it comes to file redirection. In csh, you can redirect stdout with the usual > operator, you can redirect both stdout and stderr with the >& operator, you can pipe stdout and stderr with the |& operator, but there is no single operator to redirect stderr alone.

The usual workaround is to execute the command in a sub-shell, redirecting stdout in that sub-shell to whatever file you want (/dev/null in this case), and then use the |& operator to redirect stdout and stderr of the sub-shell to the next command in the main shell.

In your case, this means something like:

( command >/dev/null ) |& grep "^[^-]" >&/tmp/fl

Because stdout is redirected to /dev/null inside the sub-shell, the |& operator will end up acting as 2>&1 in bash - since stdout is discarded in the sub-shell, nothing written to stdout will ever reach the pipe.



Related Topics



Leave a reply



Submit