Comment appeler une commande Shell à partir de Python qui contient un tuyau et capturer la sortie?
Supposons que la commande ressemble à quelque chose comme:
cat file.log | tail -1
L'équivalent Perl de ce que j'essaie de faire serait quelque chose comme:
my $string = `cat file.log | tail -1`;
Utilisez un sous-processus.PIPE, comme expliqué dans la section de documentation du sous-processus "Remplacement du pipeline Shell" :
import subprocess
p1 = subprocess.Popen(["cat", "file.log"], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["tail", "-1"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
output,err = p2.communicate()
Ou, en utilisant le module sh
, piping devient la composition de fonctions :
import sh
output = sh.tail(sh.cat('file.log'), '-1')
import subprocess
task = subprocess.Popen("cat file.log | tail -1", Shell=True, stdout=subprocess.PIPE)
data = task.stdout.read()
assert task.wait() == 0
Notez que cela ne capture pas stderr. Et si vous souhaitez également capturer stderr, vous devez utiliser task.communicate()
; appeler task.stdout.read()
puis task.stderr.read()
peut bloquer si le tampon pour stderr se remplit. Si vous souhaitez les combiner, vous devriez pouvoir utiliser 2>&1
dans le cadre de la commande Shell.
Mais vu votre cas exact,
task = subprocess.Popen(['tail', '-1', 'file.log'], stdout=subprocess.PIPE)
data = task.stdout.read()
assert task.wait() == 0
évite le besoin de la pipe du tout.
Ce:
import subprocess
p = subprocess.Popen("cat file.log | tail -1", Shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
#Try Shell=True if the above doesn't work with Shell=False
p_stdout = p.stdout.read()
p_stderr = p.stderr.read()
print p_stdout
Ou cela devrait fonctionner:
import os
result = os.system("cat file.log | tail -1")
Une autre manière similaire à Popen serait:
command=r"""cat file.log | tail -1 """
output=subprocess.check_output(command, Shell=True)
Ceci est un fork de @chown avec quelques améliorations:
import subprocess
, facilite le paramétragestderr
ou stdin
pour appeler Popen
Shell=True
est nécessaire pour appeler un interprète pour la ligne de commande #!/usr/bin/python3
import subprocess as sp
p = sp.Popen("cat app.log | grep guido", Shell=True, stdout=sp.PIPE)
output = p.stdout.read()
print(output.decode('utf-8'))
$ cat app.log
2017-10-14 22:34:12, User Removed [albert.wesker]
2017-10-26 18:14:02, User Removed [alexei.ivanovich]
2017-10-28 12:14:56, User Created [ivan.leon]
2017-11-14 09:22:07, User Created [guido.rossum]
$ python3 subproc.py
2017-11-14 09:22:07, User Created [guido.rossum]