Redirecting function output to /dev/null
If you are sure that thing does not redirect output (e.g. to /dev/tty/
, which would be standard-out again) (which I don't think), you could redirect before calling them.
#include <iostream>
#include <sstream>
void foobar() { std::cout << "foobar!\nfrob!!"; }
int main () {
using namespace std;
streambuf *old = cout.rdbuf(); // <-- save
stringstream ss;
cout.rdbuf (ss.rdbuf()); // <-- redirect
foobar(); // <-- call
cout.rdbuf (old); // <-- restore
// test
cout << "[[" << ss.str() << "]]" << endl;
}
How do I conditionally redirect the output of a command to /dev/null?
You could write a wrapper function:
redirect_cmd() {
# write your test however you want; this just tests if SILENT is non-empty
if [ -n "$SILENT" ]; then
"$@" > /dev/null
else
"$@"
fi
}
You can then use it to run any command with the redirect:
redirect_cmd echo "unsilenced echo"
redirect_cmd ls -d foo*
SILENT=1
redirect_cmd echo "nothing will be printed"
redirect_cmd touch but_the_command_is_still_run
(If all you need to do is echo with this, you can of course make the function simpler, just echoing the first argument instead of running them all as a command)
Redirecting or appending to /dev/null
It seems the behaviour for redirecting to /dev/null
via either redirect >
or append >>
is identical. A quick test shows that it also makes no difference timing wise:
Content to print:
for i in range(10**4):
print("content")
Test time command:
time python printlots.py >> /dev/null ; time python printlots.py > /dev/null
Result:
$ time python printlots.py >> /dev/null ; time python printlots.py > /dev/null
real 0m0.094s
user 0m0.047s
sys 0m0.047s
real 0m0.096s
user 0m0.031s
sys 0m0.063s
So it won't make a measureable difference which you use. It seems the reason both work is to enable developers to use /dev/null
in their code with more flexibility. If you have a program where one input parameter is the output file it prints to, and append is your default mode, not having append to /dev/null
would mean you'd have to check first what the target file is. At least that's what this answer assumes.
How can I redirect all output to /dev/null?
Redirection operators are evaluated left-to-right. You wrongly put 2>&1
first, which points 2
to the same place, as 1
currently is pointed to which is the local terminal screen, because you have not redirected 1
yet. You need to do either of the following:
2>/dev/null 1>/dev/null google-chrome &
Or
2>/dev/null 1>&2 google-chrome &
The placement of the redirect operators in relation to the command does not matter. You can put them before or after the command.
How to redirect output away from /dev/null
Since you can modify the command you run you can use a simple shell script as a wrapper to redirect the output to a file.
#!/bin/bash
"$@" >> logfile
If you save this in your path as capture_output.sh then you can add capture_output.sh to the start of your command to append the output of your program to logfile.
Will printf still have a cost even if I redirect output to /dev/null?
Pretty much.
When you redirect the stdout of the program to /dev/null
, any call to printf(3)
will still evaluate all the arguments, and the string formatting process will still take place before calling write(2)
, which writes the full formatted string to the standard output of the process. It's at the kernel level that the data isn't written to disk, but discarded by the handler associated with the special device /dev/null
.
So at the very best, you won't bypass or evade the overhead of evaluating the arguments and passing them to printf
, the string formatting job behind printf
, and at least one system call to actually write the data, just by redirecting stdout to /dev/null
. Well, that's a true difference on Linux. The implementation just returns the number of bytes you wanted to write (specified by the 3rd argument of your call to write(2)
) and ignores everything else (see this answer). Depending on the amount of data you're writing, and the speed of the target device (disk or terminal), the difference in performance may vary a lot. On embedded systems, generally speaking, cutting off the disk write by redirecting to /dev/null
can save quite some system resources for a non-trivial amount of written data.
Although in theory, the program could detect /dev/null
and perform some optimizations within the restrictions of standards they comply to (ISO C and POSIX), based on general understanding of common implementations, they practically don't (i.e. I am unaware of any Unix or Linux system doing so).
The POSIX standard mandates writing to the standard output for any call to printf(3)
, so it's not standard-conforming to suppress the call to write(2)
depending on the associated file descriptors. For more details about POSIX requirements, you can read Damon's answer. Oh, and a quick note: All Linux distros are practically POSIX-compliant, despite not being certified to be so.
Be aware that if you replace printf
completely, some side effects may go wrong, for example printf("%d%n", a++, &b)
. If you really need to suppress the output depending on the program execution environment, consider setting a global flag and wrap up printf to check the flag before printing — it isn't going to slow down the program to an extent where the performance loss is visible, as a single condition check is much faster than calling printf
and doing all the string formatting.
Redirect stderr to /dev/null
In order to redirect stderr to /dev/null use:
some_cmd 2>/dev/null
You don't need xargs
here. (And you don't want it! since it performs word splitting)
Use find's exec option:
find . -type f -name "*.txt" -exec grep -li needle {} +
To suppress the error messages use the -s
option of grep
:
From man grep
:
-s, --no-messages
Suppress error messages about nonexistent or unreadable files.
which gives you:
find . -type f -name "*.txt" -exec grep -lis needle {} +
Redirect output to /dev/null only if VERBOSE is not set
You could redirect all output using exec
:
if [[ -z $VERBOSE ]]; then
exec >/dev/null 2>&1
fi
pip install requirements.txt
If you want to restore the output later on in the script you can duplicate the file descriptors:
if [[ -z $VERBOSE ]]; then
exec 3>&1
exec 4>&2
exec >/dev/null 2>&1
fi
# all the commands to redirect output for
pip install requirements.txt
# ...
# restore output
if [[ -z $VERBOSE ]]; then
exec 1>&3
exec 2>&4
fi
Another option is to open a file descriptor to either /dev/null
or to duplicate descriptor 1
:
if [[ -z $VERBOSE ]]; then
exec 3>/dev/null
else
exec 3>&1
fi
echo "Installing Pip packages"
pip install requirements.txt >&3
Related Topics
How to Implement a Video Widget in Qt That Builds Upon Gstreamer
How Visitor Pattern Avoid Downcasting
Calculate Md5 of a String in C++
C Static Array Initialization - How Verbose Do I Need to Be
Can a C Compiler Rearrange Stack Variables
Best C++ Matrix Library for Sparse Unitary Matrices
What Happens to an Stl Iterator After Erasing It in VS, Unix/Linux
Communicate with Codesys Program on a Linux-Based Wago Pfc200 Plc
What Exactly Is the Purpose of the (Asterisk) in Pointers
C or C++ Bigint Library on Microsoft Windows
Opencv Cvsaveimage Jpeg Compression Factor
Is There Any Function Equivalent to Matlab's Imadjust in Opencv with C++
C++ Arrays as Function Arguments
Why Is My Class Non Default-Constructible
Msvc Equivalent of _Attribute_ ((Warn_Unused_Result))
Getting Errors While Compiling
What Happens When Calling the Destructor of a Thread Object That Has a Condition Variable Waiting