web-dev-qa-db-fra.com

Comment faire en sorte que le script Python soit exécuté en tant que service?

Je souhaite exécuter un script python sur un serveur CENTOS:

#!/usr/bin/env python
import socket
try:    
    import thread 
except ImportError:
    import _thread as thread #Py3K changed it.
class Polserv(object):
    def __init__(self):
        self.numthreads = 0
        self.tidcount   = 0
        self.port       = 843
        self.sock       = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind(('100.100.100.100', self.port))
        self.sock.listen(5)
    def run(self):
        while True:
            thread.start_new_thread(self.handle, self.sock.accept()) 
    def handle(self,conn,addr):
        self.numthreads += 1
        self.tidcount   += 1
        tid=self.tidcount
        while True:
            data=conn.recv(2048)
            if not data:
                conn.close()
                self.numthreads-=1
                break
            #if "<policy-file-request/>\0" in data:
            conn.sendall(b"<?xml version='1.0'?><cross-domain-policy><allow-access-from domain='*' to-ports='*'/></cross-domain-policy>")
            conn.close()
            self.numthreads-=1
            break
        #conn.sendall(b"[#%d (%d running)] %s" % (tid,self.numthreads,data) )
Polserv().run()

J'utilise $ python flashpolicyd.py et ça marche bien ... La question est de savoir comment garder ce script en marche même après la fermeture de la console ssh.

45

J'utilise this code pour démoniser mes applications. Cela vous permet start/stop/restart le script en utilisant les commandes suivantes.

python myscript.py start
python myscript.py stop
python myscript.py restart

En plus de cela, j'ai aussi un script init.d pour contrôler mon service. Cela vous permet de démarrer automatiquement le service au démarrage de votre système d'exploitation.

Voici un exemple simple pour commencer. Déplacez simplement votre code dans une classe et appelez-le à partir de la fonction run de MyDeamon.

import sys
import time

from daemon import Daemon


class YourCode(object):
    def run(self):
        while True:
            time.sleep(1)


class MyDaemon(Daemon):
    def run(self):
        # Or simply merge your code with MyDaemon.
        your_code = YourCode()
        your_code.run()


if __== "__main__":
    daemon = MyDaemon('/tmp/daemon-example.pid')
    if len(sys.argv) == 2:
        if 'start' == sys.argv[1]:
            daemon.start()
        Elif 'stop' == sys.argv[1]:
            daemon.stop()
        Elif 'restart' == sys.argv[1]:
            daemon.restart()
        else:
            print "Unknown command"
            sys.exit(2)
        sys.exit(0)
    else:
        print "usage: %s start|stop|restart" % sys.argv[0]
        sys.exit(2)

Upstart

Si vous exécutez un système d'exploitation qui utilise Upstart (par exemple, CentOS 6), vous pouvez également utiliser Upstart pour gérer le service. Si vous utilisez Upstart, vous pouvez conserver votre script tel quel et simplement ajouter quelque chose comme ceci sous /etc/init/my-service.conf

start on started sshd
stop on runlevel [!2345]

exec /usr/bin/python /opt/my_service.py
respawn

Vous pouvez ensuite utiliser start/stop/restart pour gérer votre service.

par exemple.

start my-service
stop my-service
restart my-service

Un exemple plus détaillé d'utilisation de Upstart est disponible ici .

Systemd

Si vous exécutez un système d'exploitation qui utilise Systemd (par exemple, CentOS 7), vous pouvez consulter les éléments suivants réponse Stackoverflow .

72
eandersson

J'offre deux recommandations:

surveillant

1) Installez le paquet supervisor ( instructions plus détaillées ici ):

Sudo apt-get install supervisor

2) Créez un fichier de configuration pour votre démon sur /etc/supervisor/conf.d/flashpolicyd.conf:

[program:flashpolicyd]
directory=/path/to/project/root
environment=ENV_VARIABLE=example,OTHER_ENV_VARIABLE=example2
command=python flashpolicyd.py
autostart=true
autorestart=true

3) Redémarrez supervisor pour charger votre nouveau .conf

supervisorctl update
supervisorctl restart flashpolicyd

systemd (si actuellement utilisé par votre distribution Linux)

[Unit]
Description=My Python daemon

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/project/main.py
WorkingDirectory=/opt/project/
Environment=API_KEY=123456789
Environment=API_PASS=password
Restart=always
RestartSec=2

[Install]
WantedBy=sysinit.target

Placez ce fichier dans /etc/systemd/system/my_daemon.service et l'activer avec systemctl daemon-reload && systemctl enable my_daemon && systemctl start my_daemon --no-block.

Pour afficher les journaux:

systemctl status my_daemon

65
pztrick

Mon approche non Pythonic utiliserait & suffix. C'est:

python flashpolicyd.py &

Pour arrêter le script

killall flashpolicyd.py

aussi piping & suffix with disown mettrait le processus sous superparent (supérieur):

python flashpolicyd.pi & disown
7
shookees

le premier module d'importation de votre application dans votre application qu'avec l'utilisation de getpid, obtenez l'application de pid et enregistrez-la dans un fichier. Par exemple:

import os
pid = os.getpid()
op = open("/var/us.pid","w")
op.write("%s" % pid)
op.close()

et créez un fichier bash dans /etc/init.d chemin: /etc/init.d/servername

PATHAPP="/etc/bin/userscript.py &"
PIDAPP="/var/us.pid"
case $1 in 
        start)
                echo "starting"
                $(python $PATHAPP)
        ;;
        stop)
                echo "stoping"
                PID=$(cat $PIDAPP)
                kill $PID
        ;;

esac

maintenant, vous pouvez démarrer et arrêter votre application avec la commande down:

service nom_serveur stop service nom_serveur

ou

/etc/init.d/servername stop /etc/init.d/servername start

5
Arsalan

pour mon script de python, j'utilise ...

Pour démarrer python:

start-stop-daemon --start --background --pidfile $PIDFILE --make-pidfile --exec $DAEMON

Pour arrêter le script python:

PID=$(cat $PIDFILE)
kill -9 $PID
rm -f $PIDFILE

P.S .: Désolé pour le mauvais anglais, je viens du CHILI: D

2
Rodrigo Navarrete