Really closing stdout (was: "fork and exit" needed?)

Nick Craig-Wood nick at craig-wood.com
Wed Nov 29 12:30:06 CET 2006


Mitja Trampus <nun at example.com> wrote:
>  Nick Craig-Wood wrote:
> > I'm not sure how you do open stdout to /dev/null in python though!
> > I suspect something like this...
> >   import posix
> >   posix.close(1)
> >   posix.open("/dev/null", posix.O_WRONLY)
> 
>  Yes, you're close enough... The explanations are here:
>  http://www.google.com/search?q=python%20close%20stdout,
>  I like this one in particular:
>  http://www.python.org/infogami-faq/library/why-doesn-t-closing-sys-stdout-stdin-stderr-really-close-it/
> 
>  If you explicitly want to leave file descriptors 0-2 present 
>  (Do you gain anything by not closing them? If you know, do 
>  tell...),

It is traditional I think...

>From the unix FAQ, http://www.erlenstar.demon.co.uk/unix/faq.txt :-

  6. `close()' fds 0, 1, and 2. This releases the standard in, out, and
     error we inherited from our parent process. We have no way of knowing
     where these fds might have been redirected to. Note that many daemons
     use `sysconf()' to determine the limit `_SC_OPEN_MAX'.  `_SC_OPEN_MAX'
     tells you the maximun open files/process. Then in a loop, the daemon
     can close all possible file descriptors. You have to decide if you
     need to do this or not.  If you think that there might be
     file-descriptors open you should close them, since there's a limit on
     number of concurrent file descriptors.

  7. Establish new open descriptors for stdin, stdout and stderr. Even if
     you don't plan to use them, it is still a good idea to have them open.
     The precise handling of these is a matter of taste; if you have a
     logfile, for example, you might wish to open it as stdout or stderr,
     and open `/dev/null' as stdin; alternatively, you could open
     `/dev/console' as stderr and/or stdout, and `/dev/null' as stdin, or
     any other combination that makes sense for your particular daemon.

> but pointing do /dev/null, you could do:
> 
>  null = os.open(os.devnull,os.O_WRONLY)
>  os.dup2(null,0)
>  os.dup2(null,1)
>  os.dup2(null,2)
>  os.close(null)
> 
>  Untested.

Ah, dup2() was on the tip of my mind's tongue ;-)

You could write it like this, and then it even works on Windows!

import os
import sys
import time
print os.getpid()
null = os.open(os.devnull,os.O_RDWR)
os.dup2(null, sys.stdin.fileno())
os.dup2(null, sys.stdout.fileno())
os.dup2(null, sys.stderr.fileno())
os.close(null)
print "You won't see this"
print >>sys.stderr, "Or this"
time.sleep(60)

-- 
Nick Craig-Wood <nick at craig-wood.com> -- http://www.craig-wood.com/nick



More information about the Python-list mailing list