Python - 如何用管道调用bash命令?

时间:2011-09-06 17:37:13

标签: python popen subprocess

我可以在Linux的命令行中正常运行:

$ tar c my_dir | md5sum

但是当我尝试用Python调用它时出现错误:

>>> subprocess.Popen(['tar','-c','my_dir','|','md5sum'],shell=True)
<subprocess.Popen object at 0x26c0550>
>>> tar: You must specify one of the `-Acdtrux' or `--test-label'  options
Try `tar --help' or `tar --usage' for more information.

5 个答案:

答案 0 :(得分:14)

您还必须使用subprocess.PIPE来拆分命令,在某些情况下应使用shlex.split()来防止出现异常行为:

from subprocess import Popen, PIPE
from shlex import split
p1 = Popen(split("tar -c mydir"), stdout=PIPE)
p2 = Popen(split("md5sum"), stdin=p1.stdout)

但是要创建存档并生成其校验和,您应该使用Python内置模块tarfilehashlib而不是调用shell命令。

答案 1 :(得分:4)

好的,我不确定为什么但这似乎有效:

subprocess.call("tar c my_dir | md5sum",shell=True)

任何人都知道为什么原始代码不起作用?

答案 2 :(得分:2)

您真正想要的是使用shell命令作为参数运行shell子进程:

>>> subprocess.Popen(['sh', '-c', 'echo hi | md5sum'], stdout=subprocess.PIPE).communicate()
('764efa883dda1e11db47671c4a3bbd9e  -\n', None)

答案 3 :(得分:1)

>>> from subprocess import Popen,PIPE
>>> import hashlib
>>> proc = Popen(['tar','-c','/etc/hosts'], stdout=PIPE)
>>> stdout, stderr = proc.communicate()
>>> hashlib.md5(stdout).hexdigest()
'a13061c76e2c9366282412f455460889'
>>> 

答案 4 :(得分:0)

我会在 python v3.8.10 上试试你的:

import subprocess
proc1 = subprocess.run(['tar c my_dir'], stdout=subprocess.PIPE, shell=True)
proc2 = subprocess.run(['md5sum'], input=proc1.stdout, stdout=subprocess.PIPE, shell=True)
print(proc2.stdout.decode())

要点(例如我在相关 https://stackoverflow.com/a/68323133/12361522 上的解决方案中的大纲):

  • subprocess.run()
  • bash 命令和参数没有拆分,即 ['tar c my_dir']["tar c my_dir"]
  • stdout=subprocess.PIPE 用于所有进程
  • input=proc1.stdout 前一个输出到下一个输入的链
  • 启用外壳 shell=True