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

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

passionrando
Messages : 7
Enregistré le : dim. 28 déc. 2014 22:57

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

Message par passionrando » sam. 15 juil. 2017 18:36

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

dyox
Raspinaute
Messages : 969
Enregistré le : dim. 28 déc. 2014 15:28
Localisation : Le long de la côte, au dessus du pays des bigoudennes, aïe

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

Message par dyox » sam. 15 juil. 2017 19:17

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 ?

domi
Administrateur
Messages : 3230
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

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

Message par domi » dim. 16 juil. 2017 08:51

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 ..."
Passionné de Raspberry, Arduino, ESP8266, ESP32, et objets connectés :
Spécial débutant, concevez vous-même votre domotique DIY : https://www.youtube.com/c/DomoticDIY
Conception d'une station météo DIY, et envoi des infos à votre Domotique.

Avatar du membre
zeb
Raspinaute
Messages : 280
Enregistré le : ven. 19 sept. 2014 11:04

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

Message par zeb » lun. 17 juil. 2017 13:05

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.
Dans mon panier : rpi1A+ : »:: »:: | rpi1B : »:: »:: | rpi1B+ : »:: »:: | rpi2B : »:: »:: | rpi3B : »:: »:: | rpi0 : »::

domi
Administrateur
Messages : 3230
Enregistré le : mer. 17 sept. 2014 18:12
Localisation : Seine et Marne

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

Message par domi » lun. 17 juil. 2017 20:57

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 ;-)
Passionné de Raspberry, Arduino, ESP8266, ESP32, et objets connectés :
Spécial débutant, concevez vous-même votre domotique DIY : https://www.youtube.com/c/DomoticDIY
Conception d'une station météo DIY, et envoi des infos à votre Domotique.

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

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

Message par spourre » mar. 18 juil. 2017 01:00

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

Avatar du membre
zeb
Raspinaute
Messages : 280
Enregistré le : ven. 19 sept. 2014 11:04

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

Message par zeb » mar. 18 juil. 2017 15:10

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:
Dans mon panier : rpi1A+ : »:: »:: | rpi1B : »:: »:: | rpi1B+ : »:: »:: | rpi2B : »:: »:: | rpi3B : »:: »:: | rpi0 : »::

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

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

Message par spourre » mar. 18 juil. 2017 17:19

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

Bud Spencer
Raspinaute
Messages : 1089
Enregistré le : lun. 15 août 2016 21:38

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

Message par Bud Spencer » mar. 18 juil. 2017 21:16

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).
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

spourre
Raspinaute
Messages : 735
Enregistré le : lun. 22 déc. 2014 16:50
Localisation : 67380 LINGOLSHEIM

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

Message par spourre » mar. 18 juil. 2017 23:11

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

Répondre

Retourner vers « Python »