it-swarm.com.de

Python 'Subprozess' CalledProcessError: Der Befehl '[...]' hat den Exit-Status "1" zurückgegeben

Das folgende Skript ausführen ...

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

[...]

... führt zu einem Fehler:

CalledProcessError: Der Befehl '[ping ",' -q ',' -c2 ',' -W1 ', '10 .81.3.80'] 'hat den Exit-Status 1 zurückgegeben

Das Hinzufügen von "stderr = STDOUT" in check_output hat zu keinem nützlichen Feedback geführt. 

Wie kann ich weitere Informationen zum Fehler erhalten, um ihn zu beheben?

5
Basssprosse

subprozess.check_output raises CalledProcessError bei Exit-Code ungleich Null, und ping gibt Exit-Code ungleich Null zurück, wenn etwas nicht stimmt (z. B. unbekannter Domänenname oder Standort ist inaktiv oder ICMP ist für einige blockiert Grund oder Ihre Internetverbindung ist unterbrochen).

Wenn Sie sowohl den Ausgabe- als auch den Beendigungscode überprüfen möchten, verwenden Sie 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())

Beispiele:

$ 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

Wie aus Ihrer Fehlermeldung hervorgeht, wurde der Ping mit dem Exit-Status ungleich Null beendet. Es könnte bedeuten, dass z. Die angegebene IP-Adresse ist nicht erreichbar oder Sie haben falsche Parameter eingegeben. 

Von der ping-Manpage ( http://linux.die.net/man/8/ping ):

Wenn Ping überhaupt keine Antwortpakete empfängt, wird es mit Code 1 beendet. Wenn sowohl die Anzahl der Pakete als auch die Deadline angegeben sind und bis zum Eintreffen der Deadline weniger als Count-Pakete empfangen werden, wird auch der Code 1 beendet. Bei einem anderen Fehler wird mit dem Code 2 beendet. Andernfalls wird mit dem Code 0 beendet. Dies ermöglicht es, den Exit-Code zu verwenden, um zu sehen, ob ein Host lebt oder nicht.

Sie können versuchen, CalledProcessError zu fangen und zu sehen, was in output enthalten ist. Schauen Sie hier https://docs.python.org/2/library/subprocess.html#subprocess.check_output

1