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
How to Check If One File Is Part of Other
Swift on Linux: Make Very First Step Work
How I Install Specific Fonts on My Aws Ec2 Instance
Installing Rpostgresql on Linux
Passing an Array as Command Line Argument for Linux Kernel Module
Tar Command Changing The Owner:Group While Extracting
How to Suppress Warnings in Qt Creator
How to Remove Warning: Link.Res Contains Output Sections; Did You Forget -T
Why Doesn't Time() from Time.H Have a Syscall to Sys_Time
How to Create a Core File for My Crashed Program
Git Error: Gpg Failed to Sign The Data on Linux
Atomically Swap Contents of Two Files on Linux
How to Detect If The Script Is Running on a Virtual Machine
How to Make Unix Binary Self-Contained
Sending from The Same Udp Socket in Multiple Threads
How to Change Default Number of Max Process Per User in Linux
Docker with '-User' Can Not Write to Volume with Different Ownership