python - que - subprocess popen()
Salida del subproceso Python3 (2)
Para evitar invocar un shell y descodificar nombres de archivo que podrían ser una secuencia de bytes arbitraria (excepto ''/0''
) en * nix, podría pasar el archivo como stdin:
import subprocess
with open(b''/var/log/syslog'', ''rb'') as file:
nlines = int(subprocess.check_output([''wc'', ''-l''], stdin=file))
print(nlines)
O podría ignorar cualquier error de decodificación:
import subprocess
stdoutdata = subprocess.check_output([''wc'', ''-l'', ''/var/log/syslog''])
nlines = int(stdoutdata.decode(''ascii'', ''ignore'').partition('' '')[0])
print(nlines)
Quiero ejecutar la utilidad de conteo de palabras de Linux wc para determinar el número de líneas actualmente en / var / log / syslog, para poder detectar que está creciendo. Probé varias pruebas, y mientras recibo los resultados de wc, incluye tanto el conteo de líneas como el comando (por ejemplo, var / log / syslog).
Así que está volviendo: 1338 / var / log / syslog Pero solo quiero el recuento de líneas, por lo que quiero quitar la porción / var / log / syslog, y solo mantener 1338.
He intentado convertirlo a cadena de bytestring, y luego quitando el resultado, pero sin alegría. La misma historia para convertir a cadena y stripping, decodificación, etc., todos fallan en producir la salida que estoy buscando.
Estos son algunos ejemplos de lo que obtengo, con 1338 líneas en syslog:
- b''1338 / var / log / syslog / n ''
- 1338 / var / log / syslog
Aquí hay un código de prueba que he escrito para tratar de descifrar esta tuerca, pero no hay solución:
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))
El resultado de esto es:
2A stdoutdata: b''1338 / var / log / syslog / n ''
2B stdoutdata: 1338 / var / log / syslog
2d stdoutdata: 1338 / var / log / syslog
2D stdoutdata: 1338 / var / log / syslog
Sugiero que use subprocess.getoutput()
ya que hace exactamente lo que desea: ejecutar un comando en un shell y obtener su salida de cadena (a diferencia de la salida de cadena de bytes ). Luego puede dividir en espacios en blanco y tomar el primer elemento de la lista de cadenas devuelta.
Prueba esto:
import subprocess
stdoutdata = subprocess.getoutput("wc --lines /var/log/syslog")
print("stdoutdata: " + stdoutdata.split()[0])