redirecting stdout and stderr to /dev/null
Martin A. Brown
martin at linux-ip.net
Sat May 7 15:16:00 EDT 2016
Hello there,
>I'm new to python but well versed on other languages such as C and
>Perl
>
>I'm have problems redirecting stdout and stderr to /dev/null in a
>program that does a fork and exec. T found this method googling
>around and it is quite elegant compared to to the Perl version.
>
>So to isolate things I made a much shorter test program and it
>still is not redirecting. What am I doing wrong?
>
>test program test.py
>----------------- cut here -------------------
>import sys
>import os
>
>f = open(os.devnull, 'w')
>sys.stdout = f
>sys.stderr = f
>os.execl("/bin/ping", "", "-w", "20", "192.168.1.1");
>------------------ cut here -------------------
Think about the file descriptors.
Unix doesn't care what the name is, rather that the process inherits
the FDs from the parent. So, your solution might need to be a bit
more complicated to achieve what you desire. Run the following to
see what I mean.
realstdout = sys.stdout
realstderr = sys.stderr
f = open(os.devnull, 'w')
sys.stdout = f
sys.stderr = f
print("realstdout FD: %d" % (realstdout.fileno(),), file=realstdout)
print("realstderr FD: %d" % (realstderr.fileno(),), file=realstdout)
print("sys.stdout FD: %d" % (sys.stdout.fileno(),), file=realstdout)
print("sys.stderr FD: %d" % (sys.stderr.fileno(),), file=realstdout)
That should produce output that looks like this:
realstdout FD: 1
realstderr FD: 2
sys.stdout FD: 3
sys.stderr FD: 3
I hope that's a good hint...
I like the idea of simply calling the next program using one of the
exec() variants, but you'll have to adjust the file descriptors,
rather than just the names used by Python.
If you don't need to exec(), but just run a child, then here's the
next hint (this is for Python 3.5):
import subprocess
cmd = ["ping", "-w", "20", "192.168.1.1"]
devnull = subprocess.DEVNULL
proc = subprocess.run(cmd, stdout=devnull, stderr=devnull)
proc.check_returncode()
(By the way, your "ping" command looked like it had an empty token
in the second arg position. Looked weird to me, so I removed it
in my examples.)
For subprocess.run, see:
https://docs.python.org/3/library/subprocess.html#subprocess.run
For earlier Python versions without run(), you can use Popen():
import subprocess
cmd = ["/bin/ping", "-w", "20", "192.168.1.1"]
devnull = subprocess.DEVNULL
proc = subprocess.Popen(cmd, stdout=devnull, stderr=devnull)
retcode = proc.wait()
if retcode != 0:
raise FlamingHorribleDeath
You will have to define FlamingHorribleDeath or figure out what you
want to do in the event of the various different types of
failure....if you don't then, you'll just see this:
NameError: name 'FlamingHorribleDeath' is not defined
Good luck,
-Martin
--
Martin A. Brown
http://linux-ip.net/
More information about the Python-list
mailing list