3
votes

Ctrl C ne tuera pas le sous-processus en boucle en Python

Existe-t-il un moyen approprié de créer un script qui parcourt les fichiers d'un dossier et exécute un sous-processus qui peut être tué en externe avec Ctrl C? J'ai quelque chose comme ce qui suit intégré dans un pipeline et je ne peux pas le Ctrl C à partir de la ligne de commande lorsque le processus principal est tué.

Exemple de script:

Example_script.py /path/to/some/directory/containing/files/

J'exécuterais alors le programme:

import subprocess
import os
import sys

input_directory = sys.argv[1]

for file in os.listdir(os.path.abspath(input_directory)):
    output = file + "_out.out"
    command = ['somescript.py', file, output]
    try:
        subprocess.check_call(command)
    except:
        print "Command Failed"

Pendant qu'il est en boucle, si je vois la commande a échoué, je veux utiliser Ctrl C.Cependant, elle échoue et continue d'exécuter des sous-processus supplémentaires malgré que le script principal ait été destructeur avec Ctrl C.Y a-t-il un moyen approprié d'écrire quelque chose comme celui-ci qui peut tuer les enfants (sous-processus supplémentaire) avec Ctrl C?

Toute aide, ou me diriger dans la direction est grandement appréciée. Je suis actuellement à la recherche d'une bonne méthode à faire.


2 commentaires

Pourquoi ne pas simplement quitter votre programme lorsque vous attrapez l'exception, après avoir imprimé «Échec de la commande»? - Vous pouvez devenir plus compliqué que cela en ajoutant la gestion du signal à votre code qui est appelé quand un enfant meurt, mais dans ce cas, il semble que vous vouliez simplement arrêter la boucle lorsque vous obtenez un échec. ... ou dites-vous que vous n'obtenez pas d'exception dans ce cas?


@Steve Je ne sais pas pourquoi je n'ai pas encore essayé ça. lol Cela ne m'a littéralement pas encore frappé. Merci! Si je voulais essayer une gestion du signal plus compliquée, comment procéderais-je? Est-ce que je vérifierais l'état du sous-processus lors de son retour?


3 Réponses :


5
votes

Ce que vous avez dans votre bloc try / except est trop permissif, de sorte que lorsque Ctrl + C est pressé, l'exception KeyboardInterrupt est également géré par ce même gestionnaire d'exceptions que celui qui affiche "Échec de la commande" , et comme cela est maintenant correctement géré, le flux du programme se poursuit à travers la boucle for. Ce que vous devez faire est:

  1. Remplacez sauf: par sauf Exception: afin que l'exception KeyboardInterrupt ne soit pas interceptée, de sorte qu'à tout moment Ctrl < / kbd> + C est pressé, le programme se terminera (y compris les sous-processus qui ne sont pas bloqués dans un état non terminable);
  2. Après l'instruction print , sortez de la boucle pour empêcher toute exécution ultérieure, si tel est le comportement prévu que vous souhaitez que ce programme fasse.

1 commentaires

Merci pour votre réponse. J'essaierai ceci aussi. :) Je ne manquerai pas de répondre avec une mise à jour.



0
votes

Je pense que Ctrl + Z peut également vous aider à pousser l'exécution en arrière-plan et suspendue.


0 commentaires

0
votes

Vous pouvez attraper KeyboardInterrupt , de cette façon vous pouvez gérer Ctrl + C de la manière que vous voulez.

import subprocess
import os
import sys

input_directory = sys.argv[1]

for file in os.listdir(os.path.abspath(input_directory)):
    output = file + "_out.out"
    command = ['somescript.py', file, output]
    try:
        subprocess.check_call(command)
    except KeyboardInterrupt as e:
        print "Interrupted"
        sys.exit(1)
    except:
        print "Command Failed"


0 commentaires