diferencia entre se comunica () y .stdin.write, .stdout.read o .stderr.read – python

Quiero crear una tubería entre 3 comandos:

cat = subprocess.Popen("cat /etc/passwd", stdout=subprocess.PIPE) grep = subprocess.Popen("grep ''", stdin=cat.stdout, stdout=subprocess.PIPE) cut = subprocess.Popen("cut -f 3 -d ':'", stdin=grep.stdout, stdout=subprocess.PIPE) for line in cut.stdout: # process each line here 

Pero la documentación de Python dice:

Use communicate() lugar de .stdin.write , .stdout.read o .stderr.read para evitar interlockings debido a que cualquiera de los otros buffers de tuberías del sistema operativo .stderr.read y bloqueen el proceso secundario.

Entonces, ¿cómo debo usar cut.stdout ? ¿Alguien puede explicar la documentación?

El proceso externo que ha generado puede bloquearse para siempre si está utilizando process.stdin.write sin tener conocimiento de posibles problemas de almacenamiento en búfer. Por ejemplo, si el proceso responde a su entrada de 1 línea escribiendo en su stdout una gran cantidad de datos (por ejemplo, 10-100MB) y usted continúa escribiendo en su stdin mientras no recibe estos datos, entonces el proceso se bloqueará. on write to stdout (stdout es una canalización sin nombre y el sistema operativo mantiene buffers de un tamaño particular para ellos).

Puede probar la biblioteca de iterpipes que se ocupa de estos problemas ejecutando las tareas de entrada y salida como hilos separados.

communicate está diseñada para evitar un interlocking que no se produciría en su aplicación de todos modos: está principalmente relacionada con la situación en la que tanto la stdin como la Popen stdin en un objeto Popen son canalizaciones al proceso de llamada , es decir,

 subprocess.Popen(["sometool"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

En su caso, puede leer con seguridad desde cut.stdout . Puede usar la communicate si lo encuentra conveniente, pero no es necesario.

(Tenga en cuenta que subprocess.Popen("/etc/passwd") no tiene sentido; parece que ha olvidado un cat . Además, no olvide shell=True ).