Ich möchte das Linux Word Count-Dienstprogramm wc ausführen, um die Anzahl der Zeilen in/var/log/syslog zu ermitteln, so dass ich feststellen kann, dass es wächst. Ich habe verschiedene Tests ausprobiert, und obwohl ich die Ergebnisse von wc zurückbekomme, umfasst dies sowohl die Zeilenzahl als auch den Befehl (z. B. var/log/syslog).
Also kehrt es zurück: 1338 /var/log/syslogBut Ich möchte nur die Zeilenzählung, also möchte ich den/var/log/syslog-Teil entfernen und nur 1338 behalten.
Ich habe versucht, es aus Bytestring in String umzuwandeln und dann das Ergebnis zu entfernen, aber keine Freude. Dieselbe Geschichte für die Konvertierung in Strings und Stripping, Decodierung usw. - alle erzeugen die gewünschte Ausgabe nicht.
Dies sind einige Beispiele für das, was ich mit 1338 Zeilen in syslog bekomme:
Hier ist ein Testcode, den ich geschrieben habe, um diese Nuss zu knacken, aber keine Lösung:
import subprocess
#check_output returns byte string
stdoutdata = subprocess.check_output("wc --lines /var/log/syslog", Shell=True)
print("2A stdoutdata: " + str(stdoutdata))
stdoutdata = stdoutdata.decode("utf-8")
print("2B stdoutdata: " + str(stdoutdata))
stdoutdata=stdoutdata.strip()
print("2C stdoutdata: " + str(stdoutdata))
Die Ausgabe davon ist:
2A stdoutdata: b'1338/var/log/syslog\n '
2B stdoutdata: 1338/var/log/syslog
2C stdoutdata: 1338/var/log/syslog
2D stdoutdata: 1338/var/log/syslog
Ich schlage vor, dass Sie subprocess.getoutput()
verwenden, da es genau das tut, was Sie möchten: Führen Sie einen Befehl in einer Shell aus und rufen Sie die Zeichenfolgenausgabe ab (im Gegensatz zu Byte-Zeichenfolge Ausgabe). Dann können Sie auf Whitespace aufteilen und das erste Element aus der zurückgegebenen Liste von Strings übernehmen.
Versuche dies:
import subprocess
stdoutdata = subprocess.getoutput("wc --lines /var/log/syslog")
print("stdoutdata: " + stdoutdata.split()[0])
Um das Aufrufen einer Shell zu vermeiden und Dateinamen zu dekodieren, die eine beliebige Bytefolge (außer '\0'
) auf * nix sein können, können Sie die Datei als stdin übergeben:
import subprocess
with open(b'/var/log/syslog', 'rb') as file:
nlines = int(subprocess.check_output(['wc', '-l'], stdin=file))
print(nlines)
Oder Sie könnten Dekodierungsfehler ignorieren:
import subprocess
stdoutdata = subprocess.check_output(['wc', '-l', '/var/log/syslog'])
nlines = int(stdoutdata.decode('ascii', 'ignore').partition(' ')[0])
print(nlines)
Seit Python 3.6 können Sie check_output()
eine str
anstelle von bytes
zurückgeben, indem Sie einen encoding - Parameter angeben:
check_output('wc --lines /var/log/syslog', encoding='UTF-8', Shell=True)
Äquivalent zu Curt J. Sampsons Antwort ist auch diese (es gibt einen String zurück):
subprocess.check_output('wc -l /path/to/your/file | cut -d " " -f1', universal_newlines=True, Shell=True)
von docs:
Wenn Kodierung oder Fehler angegeben werden oder Text wahr ist, werden Dateiobjekte für stdin, stdout und stderr werden mit der angegebenen .__ im Textmodus geöffnet. Kodierung und Fehler oder der Standardwert für io.TextIOWrapper. Das Das Argument universal_newlines entspricht dem Text und wird für .__ bereitgestellt. Rückwärtskompatibilität. Standardmäßig werden Dateiobjekte in binärem .__ geöffnet. Modus.
Etwas Ähnliches, aber etwas komplexer mit subprocess.run ():
subprocess.run(command, Shell=True, check=True, universal_newlines=True, stdout=subprocess.PIPE).stdout
als subprocess.check_output () könnte äquivalent zu subprocess.run () sein.