web-dev-qa-db-fra.com

Python 'sous-processus' CalledProcessError: La commande '[...]' a renvoyé un état de sortie non nul 1

Exécuter le script suivant ...

import socket                   
import sys                          

from collections import OrderedDict
from subprocess import check_output
from threading import Thread    

[...]

class IpCheck(Thread):  

    RECEIVED_PACKAGES_RE = re.compile(r'(\d+) received')

    def __init__(self, ip):                         
        Thread.__init__(self)
        self.ip = ip
        self.result = None

    def run(self):                          
        match = self.RECEIVED_PACKAGES_RE.search(
            check_output(['ping', '-q', '-c2', '-W1', self.ip])
        )

        successful_ping_count = int(match.group(1)) if match else 0

        if successful_ping_count == 0:
            self.result = 'no response'
        Elif successful_ping_count == 1:
            self.result = 'alive, but 50% package loss'
        Elif successful_ping_count == 2:
            self.result = check_snmp(self.ip)
        else:
            assert False

[...]

... entraîne une erreur:

CalledProcessError: La commande '[ping', '-q', '-c2', '-W1', '10.81.3.80 ']' a renvoyé un état de sortie non nul 1

L'ajout de "stderr = STDOUT" dans check_output n'a généré aucun retour utile. 

Comment puis-je obtenir plus d'informations sur l'erreur afin de pouvoir la résoudre?

5
Basssprosse

subprocess.check_output soulève CalledProcessError sur le code de sortie non nul, et ping renvoie un code de sortie non nul si quelque chose ne va pas (par exemple, un nom de domaine inconnu, un site est arrêté ou bloqué ICMP raison, ou votre connexion Internet est en panne).

Si vous souhaitez examiner le code de sortie et le code de sortie, utilisez subprocess.Popen :

import subprocess
import sys

site = sys.argv[1]
ping_count = 4
process = subprocess.Popen(['ping', site, '-c', str(ping_count)],
                           stdout=subprocess.PIPE,
                           stderr=subprocess.STDOUT)
returncode = process.wait()
print('ping returned {0}'.format(returncode))
print(process.stdout.read())

Exemples:

$ python ping.py google.com         <-- ping successful
ping returned 0
PING google.com (195.64.213.27) 56(84) bytes of data.
64 bytes from cache.google.com (195.64.213.27): icmp_seq=1 ttl=57 time=59.8 ms
64 bytes from cache.google.com (195.64.213.27): icmp_seq=2 ttl=57 time=2.43 ms
64 bytes from cache.google.com (195.64.213.27): icmp_seq=3 ttl=57 time=77.0 ms
64 bytes from cache.google.com (195.64.213.27): icmp_seq=4 ttl=57 time=43.8 ms

--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 2.439/45.802/77.096/27.658 ms

$ python ping.py asdasdas.com       <-- DNS resolved, but site is down
ping returned 1
PING asdasdas.com (69.172.201.208) 56(84) bytes of data.

--- asdasdas.com ping statistics ---
4 packets transmitted, 0 received, 100% packet loss, time 3024ms

$ python ping.py asdasdasdasda.com  <-- DNS failed
ping returned 2
ping: unknown Host asdasdasdasda.com
8

Comme votre message d'erreur l'a dit, le ping s'est terminé avec un statut de sortie non nul. Cela pourrait signifier que, par exemple, l'adresse IP fournie n'est pas accessible ou vous avez transmis de mauvais paramètres. 

Depuis la page de manuel ping ( http://linux.die.net/man/8/ping ):

Si ping ne reçoit aucun paquet de réponse, il se terminera avec le code 1. Si un nombre de paquets et une échéance sont spécifiés, et si moins de paquets sont reçus avant la fin de l'échéance, ils se fermeront également avec le code 1. Sur une autre erreur, il se termine avec le code 2. Sinon, il se ferme avec le code 0. Cela permet d’utiliser le code de sortie pour voir si un hôte est en vie ou non.

Vous pouvez essayer d'attraper CalledProcessError et voir ce qu'il contient dans output. Regardez ici https://docs.python.org/2/library/subprocess.html#subprocess.check_output

1