如何使用子进程popen Python [重复]

Posted

技术标签:

【中文标题】如何使用子进程popen Python [重复]【英文标题】:How to use subprocess popen Python [duplicate] 【发布时间】:2012-09-18 07:14:08 【问题描述】:

由于os.popensubprocess.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

但我想我没有正确地写出来。任何帮助,将不胜感激。谢谢

【问题讨论】:

这是 Windows 机器还是 Linux 机器? 【参考方案1】:

subprocess.Popen 接受参数列表:

from subprocess import Popen, PIPE

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

甚至还有一个section of the documentation 致力于帮助用户从os.popen 迁移到subprocess

【讨论】:

@HansThen shell=True推荐。 @Lukas Graf 因为它在代码中这么说。 @Alex shell=True 在用于处理不受信任的数据时被视为安全风险。聪明的攻击者可以修改输入以访问任意系统命令。例如。通过输入filename.swf; rm -rf / 作为文件名的值。但是,这只是一个问题,当您对 Popen 的论点的内容不安全时。 @Lukas Graf 从代码片段中我强烈怀疑这是一个示例值,由不受信任的用户提供的数据填充。但我准备就该项目休战。我的意思是没有理由不使用shell=True,除非使用 untrusted 输入。简单地声明不推荐shell=True 具有误导性。 @HansThen: P.S.不要误会我的意思,我不是想在这里解决你的问题。只是您似乎意识到shell=True 所涉及的风险,但任何偶然发现这个问题的用户可能都不会。这就是为什么我认为重要的是要强调 shell=True 实际上不被推荐,除非你确切地知道你在做什么。 @Blender 没有人说它有害——它只是危险。但除此之外,你的论点根本没有意义。 Python 标准库公开的许多 OS 函数都具有潜在危险 - 以 shutil.rmtree 为例。但这与它们是否包含在标准库中无关。我相信 UNIX 哲学 “Unix 的设计目的不是为了阻止其用户做愚蠢的事情,因为这也会阻止他们做聪明的事情。” 在很大程度上也适用于 Python。【参考方案2】:

使用sh,它会让事情变得更容易:

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

【讨论】:

sh,不错,但是和子进程的Popen不一样。 sh 与调用子进程类似。【参考方案3】:

在最近的 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 获得更多信息。感谢他的付出。

【讨论】:

【参考方案4】:

如何将 shell 命令分解为一系列参数可能并不明显,尤其是在复杂情况下。 shlex.split() 可以对 args 进行正确的标记化(我使用的是 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

【讨论】:

【参考方案5】:

以最简单的方式使用子进程!!

import subprocess
cmd = 'pip install numpy'.split()  #replace with your command
subprocess.call(cmd)

【讨论】:

以上是关于如何使用子进程popen Python [重复]的主要内容,如果未能解决你的问题,请参考以下文章

subprocess.Popen,从子进程(子)中获取变量[重复]

无法弄清楚如何在 Python 3.5 中杀死子进程 [重复]

正确关闭 Python 中的子进程 [重复]

如何从 subprocess.Popen 使用 STDIN [重复]

子进程 Popen 和 call 有啥区别(我该如何使用它们)?

如何在 Python 中终止我的子进程 [重复]