spu*_*ATX 38 python command-line pipe
如何从包含管道并捕获输出的Python调用shell命令?
假设命令是这样的:
cat file.log | tail -1
Run Code Online (Sandbox Code Playgroud)
Perl相当于我想做的事情就像:
my $string = `cat file.log | tail -1`;
Run Code Online (Sandbox Code Playgroud)
unu*_*tbu 51
使用subprocess.PIPE,如子流程文档部分"替换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()
Run Code Online (Sandbox Code Playgroud)
import sh
output = sh.tail(sh.cat('file.log'), '-1')
Run Code Online (Sandbox Code Playgroud)
import subprocess
task = subprocess.Popen("cat file.log | tail -1", shell=True, stdout=subprocess.PIPE)
data = task.stdout.read()
assert task.wait() == 0
Run Code Online (Sandbox Code Playgroud)
请注意,这不会捕获stderr.如果你想捕获stderr,你还需要使用task.communicate()
; 如果stderr的缓冲区填满task.stdout.read()
,则调用然后task.stderr.read()
可以死锁.如果要将它们组合在一起,则应该能够将其2>&1
用作shell命令的一部分.
但鉴于你的具体情况,
task = subprocess.Popen(['tail', '-1', 'file.log'], stdout=subprocess.PIPE)
data = task.stdout.read()
assert task.wait() == 0
Run Code Online (Sandbox Code Playgroud)
根本不需要管道.
这个:
import subprocess
p = subprocess.Popen("cat file.log | tail -1", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
#for shell=False use absolute paths
p_stdout = p.stdout.read()
p_stderr = p.stderr.read()
print p_stdout
Run Code Online (Sandbox Code Playgroud)
或这应该工作:
import os
result = os.system("cat file.log | tail -1")
Run Code Online (Sandbox Code Playgroud)