2
votes

Pourquoi os.system bloque-t-il l'exécution du programme?

J'essaie de créer un programme pour gérer facilement les demandes informatiques, et j'ai créé un programme pour tester si un PC sur mon réseau est actif à partir d'une liste.

Pour ce faire, j'ai écrit le code suivant:

self.btn_Ping.clicked.connect(self.ping)

def ping(self):
        hostname = self.listWidget.currentItem().text()
        if hostname:
            os.system("ping " + hostname + " -t")

Quand je l'exécute, mon programme principal se bloque et je ne peux rien faire tant que je ne ferme pas la fenêtre de commande ping. Que puis-je faire à ce sujet? Y a-t-il une autre commande que je peux utiliser pour essayer d'envoyer un ping à une machine sans geler mon programme principal?


5 commentaires

Vous pouvez simplement exécuter la commande ping avec l'argument -n 1 , de sorte qu'une seule tentative soit faite pour contacter la machine distante. L'option -t que vous utilisez est censée "Ping l'hôte spécifié jusqu'à l'arrêt." selon la documentation, donc il fait exactement ce que vous lui avez demandé.


Vous devez éviter d'utiliser os.system . Utilisez plutôt subprocess.call (["ping", hostname, "-t"]) .


je veux qu'il envoie un ping "pour toujours" ou jusqu'à ce qu'il soit annulé car parfois je suis en train de suivre un certain problème de connexion mais je veux qu'il soit séparé du programme principal


Si vous voulez qu'il soit séparé, os.system est plus erroné. Il attend que la commande se termine. N'utilisez pas os.popen à la place.


en fait, j'ai joué avec des threads et créé un nouveau thread quelque chose comme ça def ping_t1 (hôte): _thread.start_new_thread (ping_t2, (hôte,))


3 Réponses :


4
votes

Les docs indiquent que os. system () renvoie la valeur renvoyée par la commande que vous avez appelée, bloquant ainsi votre programme jusqu'à ce qu'il se termine.

Ils indiquent également que vous devez utiliser le sous-processus module à la place.


1 commentaires

J'essaie d'utiliser le sous-processus mais où puis-je obtenir la sortie?



0
votes

De la documentation ping :

ping /?

Options:
-t             Ping the specified host until stopped.
               To see statistics and continue - type Control-Break;
               To stop - type Control-C.

Donc, en utilisant -t vous attendez que cette machine s'arrête, et au cas où cette machine ne s'arrête pas, votre script Python fonctionnera indéfiniment.

Comme mentionné par HyperTrashPanda, utilisez un autre paramètre pour lancer ping , afin qu'il s'arrête après une ou plusieurs tentatives.


0 commentaires

0
votes

Comme mentionné dans la réponse de Tim Pietzcker, l'utilisation du sous-processus est fortement recommandé par rapport à os.system (et autres).

Pour séparer le nouveau processus de votre script, utilisez subprocess.Popen . Vous devriez obtenir la sortie imprimée normalement dans sys.stdout . Si vous voulez quelque chose de plus complexe (par exemple pour imprimer uniquement quelque chose si quelque chose change), vous pouvez définir les arguments stdout (et stderr et stdin ) :

Les valeurs valides sont PIPE, DEVNULL, un descripteur de fichier existant (un entier positif), un objet fichier existant et None. PIPE indique qu'un nouveau canal vers l'enfant doit être créé. DEVNULL indique que le fichier spécial os.devnull sera utilisé. Avec les paramètres par défaut Aucun, aucune redirection ne se produira; les descripteurs de fichier de l'enfant seront hérités du parent.
- documentation sur les sous-procédures.Popen , si vous faites défiler vers le bas

Si vous souhaitez obtenir le code de sortie, utilisez < code> myPopenProcess.poll () .


0 commentaires