examples example español python command subprocess pipe popen

español - subprocess python 3 example



enlaza varios comandos de Popen con tuberías (4)

Sé cómo ejecutar un comando usando cmd = subprocess.Popen y luego subprocess.communicate. La mayoría de las veces utilizo una cadena tokenizada con shlex.split como argumento ''argv'' para Popen. Ejemplo con "ls -l":

import subprocess import shlex print subprocess.Popen(shlex.split(r''ls -l''), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0]

Sin embargo, las tuberías parecen no funcionar ... Por ejemplo, el siguiente ejemplo vuelve a señalar:

import subprocess import shlex print subprocess.Popen(shlex.split(r''ls -l | sed "s/a/b/g"''), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE).communicate()[0]

¿Me puede decir lo que estoy haciendo mal, por favor?

Gracias


"" "¿Por qué no usas shell?

"" "

def output_shell (línea):

try: shell_command = Popen(line, stdout=PIPE, stderr=PIPE, shell=True) except OSError: return None except ValueError: return None (output, err) = shell_command.communicate() shell_command.wait() if shell_command.returncode != 0: print "Shell command failed to execute" return None return str(output)


Creo que quiere crear una instancia de dos objetos Popen separados aquí, uno para ''ls'' y el otro para ''sed''. Querrá pasar el primer atributo stdout del objeto Popen como argumento stdin al segundo objeto Popen.

Ejemplo:

p1 = subprocess.Popen(''ls ...'', stdout=subprocess.PIPE) p2 = subprocess.Popen(''sed ...'', stdin=p1.stdout, stdout=subprocess.PIPE) print p2.communicate()

Puedes seguir encadenando de esta manera si tienes más comandos:

p3 = subprocess.Popen(''prog'', stdin=p2.stdout, ...)

Consulte la documentación del subproceso para obtener más información sobre cómo trabajar con subprocesos.


He hecho una pequeña función para ayudar con la tubería, espero que ayude. Cadena Popens según sea necesario.

from subprocess import Popen, PIPE import shlex def run(cmd): """Runs the given command locally and returns the output, err and exit_code.""" if "|" in cmd: cmd_parts = cmd.split(''|'') else: cmd_parts = [] cmd_parts.append(cmd) i = 0 p = {} for cmd_part in cmd_parts: cmd_part = cmd_part.strip() if i == 0: p[i]=Popen(shlex.split(cmd_part),stdin=None, stdout=PIPE, stderr=PIPE) else: p[i]=Popen(shlex.split(cmd_part),stdin=p[i-1].stdout, stdout=PIPE, stderr=PIPE) i = i +1 (output, err) = p[i-1].communicate() exit_code = p[0].wait() return str(output), str(err), exit_code output, err, exit_code = run("ls -lha /var/log | grep syslog | grep gz") if exit_code != 0: print "Output:" print output print "Error:" print err # Handle error here else: # Be happy :D print output


shlex solo divide espacios de acuerdo con las reglas de shell, pero no trata con pipes.

Sin embargo, debería funcionar de esta manera:

import subprocess import shlex sp_ls = subprocess.Popen(shlex.split(r''ls -l''), stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE) sp_sed = subprocess.Popen(shlex.split(r''sed "s/a/b/g"''), stdin = sp_ls.stdout, stdout = subprocess.PIPE, stderr = subprocess.PIPE) sp_ls.stdin.close() # makes it similiar to /dev/null output = sp_ls.communicate()[0] # which makes you ignore any errors. print output

de acuerdo con la help(subprocess) ''s

Replacing shell pipe line ------------------------- output=`dmesg | grep hda` ==> p1 = Popen(["dmesg"], stdout=PIPE) p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE) output = p2.communicate()[0]

HTH