python执行shell命令查看输出_从Python运行shell命令并捕获输出

文章目录

我想编写一个函数来执行一个shell命令并返回它的输出 作为一个字符串 ,不管它是一个错误还是成功的消息。我只想得到和命令行一样的结果。

什么样的代码可以做这样的事情?

例如:

def run_command(cmd):

# ??????

print run_command('mysqladmin create test -uroot -pmysqladmin12')

# Should output something like:

# mysqladmin: CREATE DATABASE failed; error: 'Can't create database 'test'; database exists'

这个问题的答案取决于你使用的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 运行一个只有参数作为输入的程序。 1 它返回的结果与打印到 stdout 完全一样。如果您需要将输入写入 stdin

,请跳到 run 或部分。如果您想执行复杂的shell命令,请参阅本答案末尾 shell = True `的注释。

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

Modern versions of Python (3.5 or higher): run

如果您使用 Python 3.5 或更高版本,并且 不需要向后兼容性 ,new run function。它为subprocess模块提供了一个非常通用的高级API。要捕获程序的输出,请将subprocess.PIPE标志传递给stdout关键字参数。然后访问返回的的stdout属性>

CompletedProcess `对象:

>>> import subprocess

>>> result = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)

>>> result.stdout

b'total 0n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 filesn'

返回值是一个bytes对象,所以如果你想要一个合适的字符串,你需要decode它。假设被调用的进程返回一个UTF-8编码的字符串:

>>> result.stdout.decode('utf-8')

'total 0n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 filesn'

这可以全部压缩成一行:

>>> subprocess.run(['ls', '-l'], stdout=subprocess.PIPE).stdout.decode('utf-8')

'total 0n-rw-r--r-- 1 memyself staff 0 Mar 14 11:04 filesn'

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

>>> cmd = ['awk', 'length($0) > 5']

>>> input = 'foonfoofoon'.encode('utf-8')

>>> result = subprocess.run(cmd, stdout=subprocess.PIPE, input=input)

>>> result.stdout.decode('utf-8')

'foofoon'

通过传递stderr = subprocess.PIPE(capture到result.stderr)或stderr =

subprocess.STDOUT到result.stdout以及常规输出)。如果不担心安全问题,则还可以通过传递shell = True来运行更复杂的shell命令,如下面的注释中所述。

与旧的做事方式相比,这增加了一点复杂性。但是我认为这是值得的:现在你几乎可以做任何事情,你需要做的就是run函数。

Older versions of Python (2.7-3.4): check_output

如果您使用的是旧版本的Python,或者需要适度的向后兼容性,则可以使用上面简要描述的check_output函数。从Python

2.7开始,它就已经可用了。

subprocess.check_output(*popenargs, **kwargs)

它需要与Popen(见下文)相同的参数,并返回一个包含程序输出的字符串。这个答案的开头有一个更详细的使用例子。

你可以传递 stderr = subprocess.STDOUT 来确保返回的输出中包含错误信息 - 但是不要将 stderr =

subprocess.PIPE 传递给 check_output

。它可能导致[死锁](http://docs.python.org/library/subprocess.html#subprocess.check_output)。如果不担心安全问题,则还可以通过传递shell = True `来运行更复杂的shell命令,如下面的注释中所述。

如果您需要从stderr进行管道输入或将输入传递给进程,则check_output将不能执行任务。在这种情况下,请参阅下面的Popen示例。

Complex applications & legacy versions of Python (2.6 and below): Popen

如果您需要深度向后兼容性,或者您需要比check_output提供的更复杂的功能,则必须直接使用Popen对象,这些对象封装了低子进程的API级别。

Popen 构造函数接受 **没有参数的单个命令** ,或 **列表** ,其中包含命令作为其第一项,各自作为列表中的单独项目。 [shlex.split ](https://docs.python.org/3/library/shlex.html)可以帮助将字符串解析为适当的格式名单。 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($0) > 5']

>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE,

... stderr=subprocess.PIPE,

... stdin=subprocess.PIPE)

>>> out, err = p.communicate('foonfoofoon')

>>> print out

foofoo

请注意Aaron

Hall的答案,这表明在某些系统上,您可能需要设置stdout代码>,stderr和stdin全部转换成PIPE(或DEVNULL代码>来工作。

在极少数情况下,您可能需要复杂的实时输出捕获。 Vartec的答案提出了一个前进的方向,但通信以外的方法很容易发生死锁不要小心使用。

与所有上述函数一样,当安全性不是问题时,您可以通过传递shell = True来运行更复杂的shell命令。

Notes

1。运行shell命令:shell = True参数**

通常,每次调用run,check_output或Popen构造函数都会执行一个 单个程序

。这意味着没有花哨的bash式管道。如果要运行复杂的shell命令,则可以传递shell = True这三个函数都支持。

不过,这样做会引发安全问题。如果你所做的不是轻脚本,最好是分别调用每个进程,并将每个进程的输出作为输入传递给下一个进程,通过

run(cmd, [stdout=etc...], input=other_output)

或者

Popen(cmd, [stdout=etc...]).communicate(other_output)

直接连接管道的诱惑力很强,抵制它。否则,你可能会看到死锁,或者不得不做些黑客行为,比如这个。

2。 Unicode考虑因素**

check_output 在Python 2中返回一个字符串,但在Python 3中返回一个 bytes `对象。值得花点时间阅读了解unicode,如果你还没有的话。

这样比较简单,但只适用于Unix(包括Cygwin)。

import commands

print commands.getstatusoutput('wc -l file')

它返回一个带有(return_value,output)

的元组

未经作者同意,本文严禁转载,违者必究!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值