bg and fg

Graham Ashton graz at mindless.com
Mon Nov 5 10:22:59 CET 2001


In article <mailman.1004890745.16504.python-list at python.org>, "Stefan
Antoni" <sasoft at gmx.de> wrote:

> #!/usr/bin/env python
> 
> import sys, os, time
> 
> if os.fork() == 0:
> 	os.setsid # what does THAT mean? it was in the example.
> 	          # i looked into "pydoc os" but i didn't understand
> 		  # find an explantation
> 	sys.stdout = open("/dev/null", 'w')
> 	sys.stdin = open("/dev/null", 'r')
> 
> 	while 1:
> 	  pass
> 	  # daemon code:
> 
> It works :)

An alternative way to approach the stdout/stdin redirection is to create
class whose write() method does nothing; that way you're not reliant on
/dev/null existing (that may have no practical value whatsoever, I'm just
thinking about portability). This is from O'Reilly's Python Standard
Library:

  class NullDevice:
      def write(self, s):
          pass
  
  sys.stdin.close()
  sys.stdout = NullDevice()
  sys.stderr = NullDevice()

I'm not sure why your example doesn't touch stderr and leaves stdin open.

You should call os.umask(0) in there too so that child processes are able
to set their own umasks correctly (again, a security related thing). In
Python Standard Library, Fredrik Lundh also recommends calling
os.setpgrp() to make the forked process a process group leader. He doesn't
bother with os.setsid() though - does anybody know why? Stephens implies
that os.setsid() has the same effect as os.setpgrp(), and more. The
intricacies of this are probably UNIX dependent.

Stephens also recommends setting the current working directory to / (or a
chroot equivalent) incase it's launched from a mounted file system which
goes away before the process dies.

> ... but raises another question:
> How can i send commands to a daemon to (let's say) get it's status or
> terminate it without killing it? Do i need a local socket connection for
> doing something like this? Or is there a more elegant way?

There are many ways of skinning a cat. If you're running on a UNIX
computer you could do a UNIX socket instead of a TCP/IP socket. Have a
read about named pipes, and os.popen() stuff.

If your requirements are really simple you could set up a signal handler
in the daemon, and send the signal from some other process, or the shell
(with kill -HUP 1234, for example). When the daemon receives the signal it
could do any number of things, such as append a message to a log file,
etc. It all depends how scalable your solution needs to be, and what kind
of systems it needs to be able to interoperate with.

-- 
Graham



More information about the Python-list mailing list