Python

Python,第1张

Python

这个问题的答案取决于你使用的Python版本。最简单的方法是使用以下

subprocess.check_output
功能:

>>> subprocess.check_output(['ls', '-l'])b'total 0n-rw-r--r--  1 memyself  staff  0 Mar 14 11:04 filesn'

check_output
功能适用于仍在广泛使用的几乎所有版本的Python(2.7+)。2但对于较新的版本,不再推荐使用此方法。

现代版本的Python(3.5或更高版本): run

如果你使用的是Python 3.5或更高版本,并且不需要向后兼容,则建议使用新run功能。它为该

subprocess
模块提供了非常通用的高级API 。要捕获程序的输出,请将
subprocess.PIPE
标志传递给stdout关键字参数。然后访问stdout返回
CompletedProcess
对象的属性:

>>> import subprocess>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)>>> result.stdoutb'total 0n-rw-r--r--  1 memyself  staff  0 Mar 14 11:04 filesn'

返回值是一个bytes对象,因此,如果你需要正确的字符串,则需要depre它。假设被调用的进程返回一个UTF-8编码的字符串:

>>> result.stdout.depre('utf-8')'total 0n-rw-r--r--  1 memyself  staff  0 Mar 14 11:04 filesn'

所有这些都可以压缩为一种格式:

>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.depre('utf-8')'total 0n-rw-r--r--  1 memyself  staff  0 Mar 14 11:04 filesn'

如果要将输入传递给流程的stdin,bytes请将一个对象传递给input关键字参数:

>>> cmd = ['awk', 'length(
stderr=subprocess.PIPE
) > 5']>>> input = 'foonfoofoon'.enpre('utf-8')>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=input)>>> result.stdout.depre('utf-8')'foofoon'

你可以通过传递

result.stderr
(捕获到
stderr=subprocess.STDOUT
)或
result.stdout
(捕获到
shell=True
常规输出)来捕获错误。如果不考虑安全性,你还可以
subprocess.check_output(*popenargs, **kwargs)  
按照下面的说明通过传递来运行更复杂的Shell命令。

与旧的工作方式相比,这仅增加了一点复杂性。但是我认为值得这样做:现在,你仅需使用该run功能就可以完成几乎所有需要做的事情。

旧版本的Python(2.7-3.4): check_output

如果你使用的是旧版本的Python,或者需要适度的向后兼容性,则可以使用check_output上面简要介绍的函数。自python 2.7开始可用。

check_output

它采用与Popen(请参见下文)相同的参数,并返回一个包含程序输出的字符串。该答案的开头有一个更详细的用法示例。在Python 3.5及更高版本中,

check=True
等效于run使用
stdout=PIPE
stderr=subprocess.STDOUT
,仅返回stdout属性。

你可以通过

stderr=subprocess.PIPE
确保错误信息包含在返回的输出-但在Python中通过一些版本
check_output
,以
shell=True
可引起死锁。如果不考虑安全性,你还可以
check_output
按照下面的说明通过传递来运行更复杂的Shell命令。

如果你需要通过管道stderr传递输入或将输入传递给流程,check_output则将无法完成任务。Popen在这种情况下,请参见下面的示例。

复杂的应用程序和Python的旧版(2.6及以下版本): Popen

如果需要深度向后的兼容性,或者需要比

Popen
提供的功能更复杂的功能,则必须直接使用
API
对象,这些对象封装了用于子流程的低级
communicate

所述Popen构造器接受单个命令没有参数,或列表包含指令作为其第一项,其次是任意数量的参数,每个作为列表一个单独的项目。shlex.split可以帮助将字符串解析为格式正确的列表。Popen对象还接受用于进程IO管理和低级配置的许多不同参数。

发送输入和捕获输出

output = subprocess.Popen(["mycmd", "myarg"],     stdout=subprocess.PIPE).communicate()[0]
几乎始终是首选方法。如:

>>> import subprocess>>> p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, ...   stderr=subprocess.PIPE)>>> out, err = p.communicate()>>> print out...foo

要么

stdin=PIPE

如果设置

communicate
stdin
还允许你通过以下方式将数据传递到流程
>>> cmd = ['awk', 'length(
stdout
) > 5']>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,... stderr=subprocess.PIPE,... stdin=subprocess.PIPE)>>> out, err = p.communicate('foonfoofoon')>>> print outfoofoo

stderr

注艾伦·霍尔的回答,这表明在某些系统上,你可能需要设置

communicate
Vartec
以及stdin所有PIPE(或DEVNULL)得到
communicate
工作的。

在极少数情况下,你可能需要复杂的实时输出捕获。笔记的答案提出了一条前进的道路,但是

shell=True
如果不谨慎使用,则其他方法都容易出现死锁。

与上述所有功能一样,当不考虑安全性时,可以通过传递运行更复杂的Shell命令shell=True。

run,check_output

1.运行shell命令:

shell=True
参数

通常,对

run(cmd, [stdout=etc...], input=other_output)
或Popen构造函数的每次调用都会执行一个程序。这意味着没有花哨的bash风格的管道。如果要运行复杂的Shell命令,则可以传递
Popen(cmd, [stdout=etc...]).communicate(other_output)
,这三个功能都支持。

但是,这样做会引起安全问题。如果你要做的不仅仅是轻脚本编写,那么最好单独调用每个进程,并将每个进程的输出作为输入通过以下方式传递给下一个进程:

2. Unipre注意事项

要么

check_output

直接连接管道的诱惑力很强;抵抗它。否则,你可能会遇到僵局,或者不得不做类似此类的骇人听闻的事情。

bytes

unipre
在Python 2中返回一个字符串,但在Python 3中返回一个对象。如果还没有,则花一点时间来学习。



欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/4907308.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-11-12
下一篇2022-11-12

发表评论

登录后才能评论

评论列表(0条)

    保存