如何使用Python中的subprocess popen函数

154

由于os.popen正在被subprocess.popen替换,我想知道如何转换

os.popen('swfdump /tmp/filename.swf/ -d')

对于 subprocess.popen(),我尝试了:

subprocess.Popen("swfdump /tmp/filename.swf -d")
subprocess.Popen("swfdump %s -d" % (filename))  # NOTE: filename is a variable
                                                # containing /tmp/filename.swf

但我猜我没有正确地表达这个问题。任何帮助都将不胜感激。谢谢。


1
这是Windows机器还是Linux机器? - AAI
4个回答

206

subprocess.Popen接受一个参数列表:

from subprocess import Popen, PIPE

process = Popen(['swfdump', '/tmp/filename.swf', '-d'], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()

文档中甚至有一个章节专门帮助用户从os.popen迁移到subprocess


21
@HansThen 建议不要使用 shell=True - Pierre GM
9
因为代码中是这样写的。 当用于处理不受信任的数据时,shell=True被认为是一种安全风险。聪明的攻击者可以修改输入以访问任意系统命令。例如,通过将filename.swf; rm -rf /作为文件名的值输入。但是,这只有在您传递给Popen的参数内容不安全时才会成为问题。 - Hans Then
12
从这段代码片段来看,我强烈怀疑这不是一个示例值,而是由不可信用户提供的数据填充。但我准备在这个问题上停战。我的观点更多地是,除了使用 不受信任 的输入之外,没有理由不使用 shell=True。简单地声明不建议使用 shell=True 是误导性的。 - Hans Then
7
@HansThen: 顺便说一句,我并不是要找你的麻烦。只是你似乎知道使用 shell=True 存在的风险,但任何偶然发现这个问题的普通用户可能并不知道。这就是为什么我认为强调 shell=True 实际上并不被推荐,除非你确切知道自己在做什么,是很重要的。 - Lukas Graf
5
@Blender 没有人说它会有害,只是有危险。但除此之外,你的论点根本就没有意义。许多 Python 标准库暴露的操作系统函数都存在潜在的危险性——以 shutil.rmtree 为例。但这与它们是否包含在 stdlib 中无关。我认为“Unix 的哲学是_'Unix 不是为了阻止用户做蠢事而设计的,因为那也会阻止他们做聪明的事情。'_”在很大程度上也适用于 Python。 - Lukas Graf
显示剩余10条评论

17
在最近的Python版本中,subprocess进行了大幅度修改。它提供了一个全新的类Popen来处理os.popen1|2|3|4
全新的subprocess.Popen()
import subprocess
subprocess.Popen('ls -la', shell=True)

它的参数:

subprocess.Popen(args, 
                bufsize=0, 
                executable=None, 
                stdin=None, stdout=None, stderr=None, 
                preexec_fn=None, close_fds=False, 
                shell=False, 
                cwd=None, env=None, 
                universal_newlines=False, 
                startupinfo=None, 
                creationflags=0)

简单来说,新的Popen包含了被分成4个独立旧版popen的所有功能。

旧版popen

Method  Arguments
popen   stdout
popen2  stdin, stdout
popen3  stdin, stdout, stderr
popen4  stdin, stdout and stderr

您可以在Stack Abuse - Robert Robinson中获取更多信息。感谢他的贡献。


12

使用 sh 库可以使事情变得更容易:

import sh
print sh.swfdump("/tmp/filename.swf", "-d")

2
sh,这个命令很好,但它与subprocess的Popen不同。sh类似于subprocess的call。 - liuyang1

11

如何将shell命令分解成一系列参数可能并不明显,特别是在复杂情况下。 shlex.split() 可以对参数进行正确的标记化处理(我使用Blender的调用示例):

import shlex
from subprocess import Popen, PIPE
command = shlex.split('swfdump /tmp/filename.swf/ -d')
process = Popen(command, stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()

https://docs.python.org/3/library/subprocess.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接