Démon UNIX en Python

Le
Thoma
Bonjour,

J'ai trouvé plusieurs exemples permettant de détacher un script Python
de sa console et de le mettre en arrière-plan (daemon). Par contre, je
ne trouve pas d'information satisfaisante permettant, en cas de
nouvelle exécution, d'indiquer que le script réside déjà en mémoire. Si
quelqu'un avait un tuyau sur le sujet, cela m'interesserait beaucoup.

D'avance merci

Thoma

P.S. : voilà le code que j'utilise (je me suis, très fortement, inspiré
de ce script-ci : http://homepage.hispeed.ch/py430/python/daemon.py)

LOGFILE = '/root/pydaemon.log'
PIDFILE = '/root/pydaemon.pid'

import time
import datetime

def prog():
while (1):
print datetime.datetime.now()
time.sleep(1)

USERPROG = prog

import sys, os

class Log:
def __init__(self, f):
self.f = f
def write(self, s):
self.f.write(s)
self.f.flush()

def main():
sys.stdout = sys.stderr = Log(open(LOGFILE, 'a+'))
USERPROG()

if __name__ == "__main__":
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno,
e.strerror)
sys.exit(1)

os.chdir("/")
os.setsid()
os.umask(0)

try:
pid = os.fork()
if pid > 0:
open(PIDFILE,'w').write("%d"%pid)
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno,
e.strerror)
sys.exit(1)

main()
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Baptiste renard
Le #660262
Thoma wrote:

Bonjour,

J'ai trouvé plusieurs exemples permettant de détacher un script Python
de sa console et de le mettre en arrière-plan (daemon). Par contre, je
ne trouve pas d'information satisfaisante permettant, en cas de
nouvelle exécution, d'indiquer que le script réside déjà en mémoire. Si
quelqu'un avait un tuyau sur le sujet, cela m'interesserait beaucoup.

D'avance merci

Thoma

P.S. : voilà le code que j'utilise (je me suis, très fortement, inspiré
de ce script-ci : http://homepage.hispeed.ch/py430/python/daemon.py)

LOGFILE = '/root/pydaemon.log'
PIDFILE = '/root/pydaemon.pid'

import time
import datetime

def prog():
while (1):
print datetime.datetime.now()
time.sleep(1)

USERPROG = prog

import sys, os

class Log:
def __init__(self, f):
self.f = f
def write(self, s):
self.f.write(s)
self.f.flush()

def main():
sys.stdout = sys.stderr = Log(open(LOGFILE, 'a+'))
USERPROG()

if __name__ == "__main__":
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno,
e.strerror)
sys.exit(1)

os.chdir("/")
os.setsid()
os.umask(0)

try:
pid = os.fork()
if pid > 0:
open(PIDFILE,'w').write("%d"%pid)
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno,
e.strerror)
sys.exit(1)

main()


Moi, pour ce genre de chose, je fais
il y a surement mieux

#!/usr/bin/env python
import os, sys

try:
os.mkdir("/dev/shm/lock")
except OSError:
print "

print "je fais des trucs"
sys.stdin.read()


os.mrmdir("/dev/shm/lock")

NicolasP
Le #660261
Bonjour,

J'ai trouvé plusieurs exemples permettant de détacher un script Python
de sa console et de le mettre en arrière-plan (daemon). Par contre, je
ne trouve pas d'information satisfaisante permettant, en cas de
nouvelle exécution, d'indiquer que le script réside déjà en mémoire. Si
quelqu'un avait un tuyau sur le sujet, cela m'interesserait beaucoup.



Sous Windows, en C, je crée un sémaphore nommé. S'il existe déjà, c'est que l'appli tourne déjà.

J'ai jamais essayé en Python mais j'imagine que c'est également possible. Je ne sais pas non plus si les sémaphores nommés existent en Unix.

Nicolas

Thoma
Le #663623
Thoma wrote:

Bonjour,

J'ai trouvé plusieurs exemples permettant de détacher un script Python
de sa console et de le mettre en arrière-plan (daemon). Par contre, je
ne trouve pas d'information satisfaisante permettant, en cas de
nouvelle exécution, d'indiquer que le script réside déjà en mémoire. Si
quelqu'un avait un tuyau sur le sujet, cela m'interesserait beaucoup.

D'avance merci

Thoma



Moi, pour ce genre de chose, je fais
il y a surement mieux

#!/usr/bin/env python
import os, sys

try:
os.mkdir("/dev/shm/lock")
except OSError:
print "

print "je fais des trucs"
sys.stdin.read()


os.mrmdir("/dev/shm/lock")



Finalement, et suite à votre suggestion, j'ai consulté plusieurs
sources. J'en conclue que la façon la plus propre est de créer un
fichier dans /var/run/.

Maintenant, il me reste un problème à résoudre, à savoir, j'ai une
classe base :

class base:
def __init__(self):
print "base.__init__"
def launch(self):
print "base.launch"
self.__run()
def __run(self):
print "base.__run"

ainsi qu'un classe qui hérite de la classe base :

class child(base):
def __init__(self):
base.__init__(self)
print "child.__init__"
def __run(self):
print "child.__run"

testBase = base()
testBase.launch()

cela affiche :

base.__init__
base.launch
base.__run

testChild = child()
testChild.launch()

cela affiche :

base.__init__
child.__init__
base.launch
base.__run

alors que je m'attendais plutôt à :

base.__init__
child.__init__
base.launch
child.__run

Comment obtenir ce résultat ?

D'avance merci

Thoma


Jean-Baptiste renard
Le #663622
Thoma wrote:

Maintenant, il me reste un problème à résoudre, à savoir, j'ai une
classe base :

class base:
def __init__(self):
print "base.__init__"
def launch(self):
print "base.launch"
self.__run()
def __run(self):
print "base.__run"

ainsi qu'un classe qui hérite de la classe base :

class child(base):
def __init__(self):
base.__init__(self)
print "child.__init__"
def __run(self):
print "child.__run"

testBase = base()
testBase.launch()

cela affiche :

base.__init__
base.launch
base.__run

testChild = child()
testChild.launch()

cela affiche :

base.__init__
child.__init__
base.launch
base.__run

alors que je m'attendais plutôt à :

base.__init__
child.__init__
base.launch
child.__run

Comment obtenir ce résultat ?



La réponse est toute bête. Ca vient du nom de ta fonction __run
si tu avais écrit def run(...) la fonction aurait été public
si tu avais écrit def _run(...) la fonction aurait été protégée (donc
héritable)
si tu avais écrit def __run(...) la fonction aurait été privée

Dans ton exemple,
Si tu fais un print dir(testChild) ca donne
['__doc__', '__init__', '__module__', '_base__run', '_child__run', 'launch']

Maintenant remplace ta méthode __run par _run (il n'y a qu'un tiret)
le print dir(testchild) affiche
['__doc__', '__init__', '__module__', '_run', 'launch']
et tu aura le résultat que tu attends

Cordialement

Eric Brunel
Le #663365
On Mon, 17 Dec 2007 21:34:14 +0100, Jean-Baptiste renard
[snip]
La réponse est toute bête. Ca vient du nom de ta fonction __run
si tu avais écrit def run(...) la fonction aurait été public
si tu avais écrit def _run(...) la fonction aurait été protégée (donc
héritable)
si tu avais écrit def __run(...) la fonction aurait été privée


AMHA, cette terminologie C++/Java-ienne est particulièrement inadaptée à
ce qui se passe vraiment... Du point de vue de Python, il n'y a aucune
différence entre run et _run: l'une n'est pas plus "publique" ou
"protégée" que l'autre. Le simple-underscore en préfixe est strictement
une convention pour indiquer que la méthode ne fait pas partie de
l'interface de la classe et qu'elle est susceptible de changer de
sémantique ou de disparaître selon le bon vouloir du développeur. C'est
tout.

De même, une méthode __run n'est pas "privée"; son nom est simplement
modifié pour inclure le nom de la classe de façon à permettre qu'un
attribut ou une méthode d'une sous-classe ou d'une super-classe ait le
même nom. Ca ne la rend pas privée pour autant, puisqu'on peut l'appeler
sans aucun problème de l'extérieur en appelant _NomDeLaClasse__run.

Donc je dirais plutôt:
- run: méthode faisant partie de l'interface de la classe; usage "libre";
- _run: méthode d'implémentation ne faisant pas partie de l'interface de
la classe; à n'utiliser que si on sait ce qu'on fait et/ou qu'on ne craint
pas les problèmes qu'il pourrait y avoir dans des versions futures;
- __run: pareil que _run, mais pour l'appeler, il faut en plus faire le
"name mangling" nous-même (_NomDeLaClasse__run).

Mes [€$£¥] 0.02...
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"

Jean-Baptiste renard
Le #663364
Eric Brunel wrote:

On Mon, 17 Dec 2007 21:34:14 +0100, Jean-Baptiste renard
AMHA, cette terminologie C++/Java-ienne est particulièrement inadaptée à
ce qui se passe vraiment...
Je me doutais bien que ça allait provoquer quelques réactions :-)


C'est en effet peu adapté, mais j'essayais de raccrocher est des notions
plus "universelles".

Eric Brunel
Le #663363
On Tue, 18 Dec 2007 22:22:06 +0100, Jean-Baptiste renard

Eric Brunel wrote:

On Mon, 17 Dec 2007 21:34:14 +0100, Jean-Baptiste renard
AMHA, cette terminologie C++/Java-ienne est particulièrement inadaptée à
ce qui se passe vraiment...
Je me doutais bien que ça allait provoquer quelques réactions :-)


C'est en effet peu adapté, mais j'essayais de raccrocher est des notions
plus "universelles".


Je ne vois pas ce que le C++ ou le Java ont d'universel... A ma
connaissance, c'est quand même un peu les seuls languages OO qui ont ces
notions de public/protégé/privé...
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"


Jean-Baptiste renard
Le #663362
Eric Brunel wrote:

On Tue, 18 Dec 2007 22:22:06 +0100, Jean-Baptiste renard
Je ne vois pas ce que le C++ ou le Java ont d'universel... A ma
connaissance, c'est quand même un peu les seuls languages OO qui ont ces
notions de public/protégé/privé...


Universelle dans le sens qui fait partie du cursus de base universitaire.

Sinon, Delphi, ruby, D, C#, Visual Basic, ADA, ont d'après mes souvenirs ces
notions. (je ne suis pas très sur pour ruby)

Eric Brunel
Le #663361
On Wed, 19 Dec 2007 21:23:06 +0100, Jean-Baptiste renard

Eric Brunel wrote:

On Tue, 18 Dec 2007 22:22:06 +0100, Jean-Baptiste renard
Je ne vois pas ce que le C++ ou le Java ont d'universel... A ma
connaissance, c'est quand même un peu les seuls languages OO qui ont ces
notions de public/protégé/privé...


Universelle dans le sens qui fait partie du cursus de base universitaire.

Sinon, Delphi, ruby, D, C#, Visual Basic, ADA, ont d'après mes souvenirs
ces
notions. (je ne suis pas très sur pour ruby)


<mode coupeur_de_cheveux_en_quatre="on">
D et C# venant du C++ et du Java, ça n'est pas vraiment étonnant.
Si j'ai bien compris, ADA a une notion de privé, mais qui correspond à la
notion de protégé en C++/Java: les sous-classes ont accès aux définitions.
Et à ma connaissance, ni Smalltalk, ni Eiffel, ni Objective-C, ni O'Caml
n'ont cette "hiérarchie" public/protégé/privé...
Et je vais me retenir très fort de faire un commentaire sur le cursus de
base universitaire...
</mode>

Bon on va peut-être arrêter, on est un peu total HS, là...
--
python -c "print ''.join([chr(154 - ord(c)) for c in
'U(17zX(%,5.zmz5(17l8(%,5.Z*(93-965$l7+-'])"


Thoma
Le #663360
Bonjour,

J'ai trouvé plusieurs exemples permettant de détacher un script Python
de sa console et de le mettre en arrière-plan (daemon). Par contre, je
ne trouve pas d'information satisfaisante permettant, en cas de
nouvelle exécution, d'indiquer que le script réside déjà en mémoire. Si
quelqu'un avait un tuyau sur le sujet, cela m'interesserait beaucoup.

D'avance merci

Thoma

P.S. : voilà le code que j'utilise (je me suis, très fortement, inspiré
de ce script-ci : http://homepage.hispeed.ch/py430/python/daemon.py)

LOGFILE = '/root/pydaemon.log'
PIDFILE = '/root/pydaemon.pid'

import time
import datetime

def prog():
while (1):
print datetime.datetime.now()
time.sleep(1)

USERPROG = prog

import sys, os

class Log:
def __init__(self, f):
self.f = f
def write(self, s):
self.f.write(s)
self.f.flush()

def main():
sys.stdout = sys.stderr = Log(open(LOGFILE, 'a+'))
USERPROG()

if __name__ == "__main__":
try:
pid = os.fork()
if pid > 0:
# exit first parent
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno,
e.strerror)
sys.exit(1)

os.chdir("/")
os.setsid()
os.umask(0)

try:
pid = os.fork()
if pid > 0:
open(PIDFILE,'w').write("%d"%pid)
sys.exit(0)
except OSError, e:
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno,
e.strerror)
sys.exit(1)

main()


Merci à tous.

Thoma

Publicité
Poster une réponse
Anonyme