redirecting stdout and stderr to /dev/null

Jim Dodgen jim at dodgen.us
Sat May 7 19:54:01 EDT 2016


*Thanks for the help*



On Sat, May 7, 2016 at 12:16 PM, Martin A. Brown <martin at linux-ip.net>
wrote:

>
> 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.)
>

The empty token is needed but useless, it is arg[0] most people just repeat
the program name


>
> 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/


seems not to find subprocess.DEVNULL

I'm on 2.7.6  Ubuntu, and 2.7.9 on Raspbian  I expect I need 3.5

here are some Tracebacks I get, the second one is when I tried os.devnull
in place of subprocess.DEVNULL


Traceback (most recent call last):
  File "test.py", line 5, in <module>
    devnull = subprocess.DEVNULL
AttributeError: 'module' object has no attribute 'DEVNULL'


Traceback (most recent call last):
  File "test.py", line 6, in <module>
    proc = subprocess.Popen(cmd, stdout=os.devnull, stderr=os.devnull)
  File "/usr/lib/python2.7/subprocess.py", line 702, in __init__
    errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
  File "/usr/lib/python2.7/subprocess.py", line 1128, in _get_handles
    c2pwrite = stdout.fileno()
AttributeError: 'str' object has no attribute 'fileno'


One other observation it looks as Popen behaves the same way as my fork
exec would



More information about the Python-list mailing list