By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
438,428 Members | 1,340 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 438,428 IT Pros & Developers. It's quick & easy.

"fork and exit" needed?

P: n/a
Hi

I'm a Python newbie, and would like to rewrite this Perl scrip
to be run with the Asterisk PBX:

http://www.voip-info.org/wiki/view/Asterisk+NetCID

Anyone knows if those lines are necessary, why, and what their
alternative is in Python?

-------
open STDOUT, '>/dev/null';
fork and exit;
-------

Thank you.
Nov 27 '06 #1
Share this Question
Share on Google+
13 Replies


P: n/a
Vincent Delporte wrote:
Hi

I'm a Python newbie, and would like to rewrite this Perl scrip
to be run with the Asterisk PBX:

http://www.voip-info.org/wiki/view/Asterisk+NetCID

Anyone knows if those lines are necessary, why, and what their
alternative is in Python?
open STDOUT, '>/dev/null';
Either redefine stdout to an open file object for /dev/null or run the
script as "script.py >/dev/null"
fork and exit;
something like:

if os.fork():
sys.exit(0)

Tells the parent to exit after the fork while the child keeps running.
These are both steps in becoming a daemon (the comp.unix.programmer
FAQ, while skewed toward C, explains why some of these steps are
needed).

Nov 28 '06 #2

P: n/a
In <8o********************************@4ax.com>, Vincent Delporte wrote:
Anyone knows if those lines are necessary, why, and what their
alternative is in Python?

-------
open STDOUT, '>/dev/null';
sys.stdout = open(os.devnull, 'w')

Ciao,
Marc 'BlackJack' Rintsch
Nov 28 '06 #3

P: n/a
Marc 'BlackJack' Rintsch <bj****@gmx.netwrote:
In <8o********************************@4ax.com>, Vincent Delporte wrote:
Anyone knows if those lines are necessary, why, and what their
alternative is in Python?

open STDOUT, '>/dev/null';

sys.stdout = open(os.devnull, 'w')
This doesn't have the desired effect

If you run this

import os,sys,time
print os.getpid()
sys.stdout = open(os.devnull, 'w')
time.sleep(60)

It prints its pid.

$ ls -l /proc/32004/fd
total 4
lrwx------ 1 ncw ncw 64 Nov 28 09:55 0 -/dev/pts/17
lrwx------ 1 ncw ncw 64 Nov 28 09:55 1 -/dev/pts/17
lrwx------ 1 ncw ncw 64 Nov 28 09:55 2 -/dev/pts/17
l-wx------ 1 ncw ncw 64 Nov 28 09:55 3 -/dev/null

That quite clearly shows that stdout isn't /dev/null which is required
for proper deamonisation under unix.

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)
--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Nov 28 '06 #4

P: n/a
Nick Craig-Wood wrote:
If you run this

import os,sys,time
print os.getpid()
sys.stdout = open(os.devnull, 'w')
time.sleep(60)

It prints its pid.
and not only that, if you run

print "world",
print "hello"

it prints "hello world" in the wrong order!

</F>

Nov 28 '06 #5

P: n/a
Dennis Lee Bieber <wl*****@ix.netcom.comwrote:
On Tue, 28 Nov 2006 04:30:09 -0600, Nick Craig-Wood
<ni**@craig-wood.comdeclaimed the following in comp.lang.python:

If you run this

import os,sys,time
print os.getpid()
sys.stdout = open(os.devnull, 'w')
time.sleep(60)

It prints its pid.
I would hope so, as you performed the print BEFORE reassigning
stdout...
That is what I intended. I wanted the pid to look in /proc/<pid>/fd
to see what file descriptors were really open.
import os,sys,time
print "pre:", os.getpid()
sys.stdout = open(os.devnull, 'w')
print "post:", os.getpid()
time.sleep(60)

(Granted, I'm on WinXP; I also suspect the original stdout is still open
in the background, maybe dualled with stderr?)
Yes that is the point - the original stdout is still open.

I don't think this discussion is relevant to windows though - windows
has its own way of making daemons.

--
Nick Craig-Wood <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Nov 28 '06 #6

P: n/a
Nick Craig-Wood wrote:
>>open STDOUT, '>/dev/null';
sys.stdout = open(os.devnull, 'w')
$ ls -l /proc/32004/fd
total 4
lrwx------ 1 ncw ncw 64 Nov 28 09:55 0 -/dev/pts/17
lrwx------ 1 ncw ncw 64 Nov 28 09:55 1 -/dev/pts/17
lrwx------ 1 ncw ncw 64 Nov 28 09:55 2 -/dev/pts/17
l-wx------ 1 ncw ncw 64 Nov 28 09:55 3 -/dev/null

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/l...ally-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...), 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.

More info on file descriptors and python here:
http://docs.python.org/lib/os-fd-ops.html

Mitja
Nov 29 '06 #7

P: n/a
On Tue, 28 Nov 2006 08:30:03 -0600, Nick Craig-Wood
<ni**@craig-wood.comwrote:
> import os,sys,time
print "pre:", os.getpid()
sys.stdout = open(os.devnull, 'w')
print "post:", os.getpid()
time.sleep(60)

(Granted, I'm on WinXP; I also suspect the original stdout is still open
in the background, maybe dualled with stderr?)

Yes that is the point - the original stdout is still open.

I don't think this discussion is relevant to windows though - windows
has its own way of making daemons.
Thanks everyone. I'll see if the Python script runs OK in an Asterisk
PBX on Linux.
Nov 29 '06 #8

P: n/a
Mitja Trampus <nu*@example.comwrote:
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/l...ally-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 <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Nov 29 '06 #9

P: n/a
On Tue, 28 Nov 2006 04:30:09 -0600, Nick Craig-Wood
<ni**@craig-wood.comwrote:
>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)
Thanks everyone, but no go :-/ Neither the above nor "sys.stdout =
open(os.devnull, 'w') " trigger the application.

This is a script that is launched by the Asterisk open-source PBX
server when a call comes in. Its goal is to broadcast some messages to
a Windows caller ID application that is installed on all client hosts
so that they know who's calling.

Before I go ask in an Asterisk forum, is there some Python-related
issue that experienced Python developers can spot in this rewrite of a
Perl script that works?

Here's the original Perl script:
http://www.voip-info.org/wiki/view/Asterisk+NetCID

Here's my Python rewrite:
http://codecomplete.free.fr/asterisk/python_cid.txt

Yes, I changed the UDP port from 42685 to 42687 so that my development
client host is the only one getting the broadcast :-)

Thank you!
Nov 30 '06 #10

P: n/a
On Thu, 30 Nov 2006 15:38:11 +0100, Vincent Delporte <bl*@bla.com>
wrote:
>Here's my Python rewrite:
http://codecomplete.free.fr/asterisk/python_cid.txt
More information. Here's what Asterisk says when I call in:

*CLI>

-- Executing LookupCIDName("SIP/fxo-0844e458", "") in new stack

-- Changed Caller*ID name to Work

-- Executing AGI("SIP/fxo-0844e458",
"ncid.python.agi|087077XXXX|Bureau Freebox") in new stack

-- Launched AGI Script /var/lib/asterisk/agi-bin/ncid.python.agi
Failed to execute '/var/lib/asterisk/agi-bin/ncid.python.agi': Exec
format error

-- AGI Script ncid.python.agi completed, returning 0

FWIW, I wrote the original in a Windows text editor, and copy-pasted
the script in Asterisk by sshing into the server. CRLF vs. CR issue?
Something else?

Thanks.
Nov 30 '06 #11

P: n/a
On Thu, 30 Nov 2006 15:48:53 +0100, Vincent Delporte <bl*@bla.com>
wrote:
-- Launched AGI Script /var/lib/asterisk/agi-bin/ncid.python.agi
Failed to execute '/var/lib/asterisk/agi-bin/ncid.python.agi': Exec
format error
Stupid me :-/ Forgot the all-important

#!/usr/bin/python

Sorry for the disturbance..
Nov 30 '06 #12

P: n/a
Vincent Delporte wrote:
On Thu, 30 Nov 2006 15:38:11 +0100, Vincent Delporte <bl*@bla.com>
wrote:
>Here's my Python rewrite:
http://codecomplete.free.fr/asterisk/python_cid.txt
First line of your script should be:

#! /usr/bin/env python

which is how Linux knows what interpreter to use for the script.

HTH,
Mike

--
________________________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://www.vrplumber.com
http://blog.vrplumber.com

Nov 30 '06 #13

P: n/a
On Thu, 30 Nov 2006 10:18:24 -0500, "Mike C. Fletcher"
<mc******@vrplumber.comwrote:
>which is how Linux knows what interpreter to use for the script.
Thanks. That's what I found out after a bit more research. I didn't
pay attention to this because it's not needed to run under Windows,
and I was focusing on the fork() and stdout thing.
Nov 30 '06 #14

This discussion thread is closed

Replies have been disabled for this discussion.