运行包含管道的命令行并将结果显示在STDOUT上

51 投票
6 回答
52461 浏览
提问于 2025-04-17 01:50

如何在Python中调用一个包含管道的命令,并获取它的输出呢?

假设这个命令是这样的:

cat file.log | tail -1

在Perl中,我想做的事情可以这样写:

my $string = `cat file.log | tail -1`;

6 个回答

8
import subprocess
task = subprocess.Popen("cat file.log | tail -1", shell=True, stdout=subprocess.PIPE)
data = task.stdout.read()
assert task.wait() == 0

请注意,这段代码并没有捕获错误输出(stderr)。如果你想同时捕获错误输出,就需要使用 task.communicate();如果你先调用 task.stdout.read() 再调用 task.stderr.read(),可能会导致程序卡住,因为错误输出的缓冲区可能会满。如果你想把它们合在一起,可以在命令中使用 2>&1

不过根据你的具体情况,

task = subprocess.Popen(['tail', '-1', 'file.log'], stdout=subprocess.PIPE)
data = task.stdout.read()
assert task.wait() == 0

完全可以不需要使用管道。

8

这个:

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

或者这个应该可以用:

import os
result = os.system("cat file.log | tail -1")
68

使用subprocess.PIPE,就像在subprocess文档中提到的那样,具体可以查看“替代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()

或者,使用sh模块,管道操作就变成了函数的组合

import sh
output = sh.tail(sh.cat('file.log'), '-1')

撰写回答