Page 1 sur 4

Arrêter un script Python lancé dans rc.local

Posté : sam. 15 juil. 2017 18:36
par passionrando
Bonjour à tous,

On trouve beaucoup de questions pour lancer un script Python au boot du RPI, mais peu sur comment faire pour l'arrêter !

Je lance bien mon script avec un "&" pour le mettre en tache de fond. Par contre CTRL+C n'a aucun effet. Car je suis sur une ligne du Shell. ^C s'affiche.
Je peux exécuter des commandes, etc... mais entre s'intercalent les lignes qui arrivent de mon script (puisqu'il tourne toujours)
En fait ce script récupère les trames de mon installation domotique, c'est une boucle qui tourne indéfiniment. Il faut donc l'arrêter avant de taper des commandes sur le RPI.

Evidemment, comme le script est lancé au boot, aucun user n'est encore logué... d'où le problème (je pense), puisque si je me logue et lance le script manuellement il s'interrompt sans problème avec CTRL+C

J'ai essayé sans le faire tourner en tâche de fond, mais c'est pire... Là, je n'ai même pas la main sur le Shell

Idée ?
Merci

Michael

Re: Arrêter un script Python lancé dans rc.local

Posté : sam. 15 juil. 2017 19:17
par dyox
Bonsoir,
On trouve beaucoup de questions pour lancer un script Python au boot du RPI, mais peu sur comment faire pour l'arrêter !
=> Quelle est la solution que vous avez retenue ?

Re: Arrêter un script Python lancé dans rc.local

Posté : dim. 16 juil. 2017 08:51
par domi
Bonjour
passionrando a écrit :...Evidemment, comme le script est lancé au boot, aucun user n'est encore logué... d'où le problème (je pense), ....
Il y a obligatoirement un user qui lance votre script, exécuter la commande suivante :

Code : Tout sélectionner

ps -ef | grep NOM_SCRIPT
En remplaçant bien entendu NOM_SCRIPT par le nom de votre script.
Vous verrez ainsi qu'elle USER lance le script.
Juste après le USER il y a un numéro que l'on va appeler NUMERO dans le script ci-dessous, mais que vous remplacerez par le numéro fourni.
Vous faites la commande suivante :

Code : Tout sélectionner

sudo kill -9 NUMERO
Le process doit être tué. Pour le vérifier refaite la commande "ps -ef ...."
Si le process existe toujours, une solution plus radical est de remplacer le "kill -9 ...." par un "kill -15 ..."

Re: Arrêter un script Python lancé dans rc.local

Posté : lun. 17 juil. 2017 13:05
par zeb
Plop,
domi a écrit :Vous faites la commande suivante :

Code : Tout sélectionner

sudo kill -9 NUMERO
Le process doit être tué. Pour le vérifier refaite la commande "ps -ef ...."
Si le process existe toujours, une solution plus radical est de remplacer le "kill -9 ...." par un "kill -15 ..."

@Domi

Alerte !!!! Mélangeage en cours.

Domi, c'est très vilain de faire un kill -9. Ce signal n'est pas trapable et c'est lui qui est radical.
Donc d'abord un SIGTERM, puis seulement après et en cas de complication et en dernier et ultime recours, un SIGKILL.

Voici les signaux à bien connaître : SIGINT (2), SIGTERM (15), SIGKILL (9), SIGHUP(2), SIGUSR1 et SIGUSR2.
* SIGINT, c'est l'interruption. C'est le signal que le shell envoie au processus de premier plan quand il recçoit un Ctrl-C.
* SIGTERM, c'est la demande de terminaison. C'est le signal par défaut de la commande kill. Le processus enregistre la demande et à son tour, exécute la procédure associée. Si l'utilisateur ne l'a pas redéfinie, c'est la procédure par défaut qui est exécutée : le processus informe ses éventuels processus fils et se termine proprement.
* SIGKILL, c'est l'assassinat. Ce signal ne peut pas être détourné par le processus. C'est violent, sanglant, et à réserver aux cas les plus difficiles.
* SIGHUP, c'est un hang-up. L'utilisateur a recroché. C'est la fin de la session.
* SIGUSR1 et 2, ce sont les signaux réservés à l'usage de l'utilisateur. Les procédures par défaut associées à ces signaux ne font rien. Au programmeur de les implémenter.

Puisqu'un équivalent à Ctrl-C conviendrait à Passionrando, il faut lui recommander un SIGINT, ou encore mieux, un simple SIGTERM.

------------------------

@Passionrando

Eh, mon gars, t'as oublié un ptit truc. C'est de rediriger la sortie de ton processus envoyé en tâche de fond.
Avant de mettre un & derrière une ligne de commande, il faut se demander quoi faire des sorties standard (1) et d'erreur (2) de ce que l'on backgroundize (ça existe, ce mot là ?)

Exemples :

Code : Tout sélectionner

$ mon_script.py 1>/dev/null 2>/dev/null &
$ mon_script.py >>/var/log/mon_script.log 2>&1 &
$ mon_script.py >/tmp/mon_script.log 2>/tmp/mon_script.err &
Redirections :
* 1> et > sont des synonymes.
* n>&m (où n et m sont des nombres), redirige le fichier identifié par le descripteur n vers le fichier de descripteur m. Pour n=2,m=1, c'est STDERR => STDOUT.
* >> c'est pour ajouter plutôt que d'écraser le fichier, s'il existe déjà.

Le premier exemple envoie tout null part.
Le second, tout dans un fichier, sans l'écraser.
Le troisième, la sortie standard dans un fichier, la sortie d'erreur dans un autre.

Re: Arrêter un script Python lancé dans rc.local

Posté : lun. 17 juil. 2017 20:57
par domi
zeb a écrit :Domi, c'est très vilain de faire un kill -9. Ce signal n'est pas trapable et c'est lui qui est radical.
Donc d'abord un SIGTERM, puis seulement après et en cas de complication et en dernier et ultime recours, un SIGKILL.
Tiens ! tiens !!!
Va falloir que je me remette de niveau moi...
J'utilise DEBIAN depuis je ne sais combien de temps, ça doit faire une dizaine d'année, j'ai commencé avec la version SARGE, la 3.1 sortie en juin 2005.
Et bien je ne connaissait pas SIGTERM, va falloir que j'étudie cela, car des KILL -9, j'en ai fait quelques un !!!!
Et il m'arrive encore d'en faire ;-)
C'est vrai que j'ai mélangé, c'est le kill -9 le plus radical.

Désolé Zeb, me tape plus sur la tête, promis je me met au niveau pour les SIGTERM ;-)

Re: Arrêter un script Python lancé dans rc.local

Posté : mar. 18 juil. 2017 01:00
par spourre
Bsr,

Kill -9 peut être utile en cas de programme devenu incontrôlable mais il faut savoir et comprendre ce que l'on fait.
Tout ça a déjà été traité il y a peu de temps, dans un autre fil:
viewtopic.php?f=4&t=3957
Je pense que la plupart des réponses que cherche le PO s'y trouve (surtout que l'on ne s'est pas limité au web)..

Sylvain

Re: Arrêter un script Python lancé dans rc.local

Posté : mar. 18 juil. 2017 15:10
par zeb
domi a écrit :Et bien je ne connaissait pas SIGTERM
Mais si M. Jourdain, tu faisais des SIGTERM, mais sans le savoir (Kill sans paramètre envoie un SIGTERM).
:D
spourre a écrit :[..]
Tout ça a déjà été traité il y a peu de temps, dans un autre fil:
viewtopic.php?f=4&t=3957
Je pense que la plupart des réponses que cherche le PO s'y trouve (surtout que l'on ne s'est pas limité au web)..
+1 :ugeek:

Re: Arrêter un script Python lancé dans rc.local

Posté : mar. 18 juil. 2017 17:19
par spourre
zeb a écrit :Mais si M. Jourdain, tu faisais des SIGTERM, mais sans le savoir (Kill sans paramètre envoie un SIGTERM).
....
UNIX, POSIX, c'est MAGIX :ugeek:
Je suis un grand naïf et je reste émerveillé de la cohérence d'un système, inventé dans les années 70 et ayant explosé grâce à l'arrivée des processeurs 68xxxx (Motorola) et dont les principes fondamentaux sont toujours d'actualité.

Sylvain

Re: Arrêter un script Python lancé dans rc.local

Posté : mar. 18 juil. 2017 21:16
par Bud Spencer
UNIX ou pas, tuer un process sans même savoir si un signal peut être reçu pour assurer une sortie propre, et encore pire, sans même savoir ce qui se passe dans cette boucle infernale, ça reste avant tout de la méthode de bourrin (l’admin$ doit parfois être bourrin, mais il l’assume, et c’est pour ça qu’on le paie très bien :mrgreen: :lol: ) .

Si c’est codé avec des palmes et qu’une boucle infinie tourne dans le thread principal, la moindre des choses, c’est au grand minimum d’assurer une sortie façon ‘bourrin’ mais ‘contrôlée’ -> https://docs.python.org/2/library/signal.html

Si on veut faire correctement, on ne programme pas de boucle infinie sans possibilité de break par une interrupt. quelconque (system, soft, hard, socket … même avec un langage aussi ‘pythoyable’ que python, les options propres ne manques pas).

Le point positif dans tout ça, c’est la petite leçon (ou révision) sur les différents SIG_ (merci zeb).

Re: Arrêter un script Python lancé dans rc.local

Posté : mar. 18 juil. 2017 23:11
par spourre
Bud Spencer a écrit :UNIX ou pas, tuer un process sans même savoir si un signal peut être reçu pour assurer une sortie propre, et encore pire, sans même savoir ce qui se passe dans cette boucle infernale, ça reste avant tout de la méthode de bourrin .
C'est bien pour cela que j'ai pris la peine d'ajouter qu'il faut utiliser cet outil en comprenant ce que l'on fait.
Pour éviter toute tentation de querelle de chapelle, je précise que cela concerne tous les OS, il faut maîtriser un certains nombre de concepts.

Sylvain