我想编写一个函数,它将执行一个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版本。最简单的方法是使用^{} 函数:
check_output
运行一个只接受参数作为输入的程序。1它返回打印到stdout
的结果。如果需要向stdin
写入输入,请跳到run
或Popen
部分。如果要执行复杂的shell命令,请参阅本答案末尾关于shell=True
的说明。check_output
函数可以在几乎所有仍在广泛使用的Python版本(2.7+).2上工作,但对于较新的版本,它不再是推荐的方法。Python的现代版本(3.5或更高版本):
run
如果您使用的是Python 3.5或更高版本,并且不需要向后兼容,建议使用new ^{} function 。它为} 对象的
subprocess
模块提供了一个非常通用的高级API。要捕获程序的输出,请将subprocess.PIPE
标志传递给stdout
关键字参数。然后访问返回的^{stdout
属性:返回值是一个
bytes
对象,因此如果您想要一个合适的字符串,就需要decode
它。假设调用的进程返回一个UTF-8编码的字符串:所有这些都可以压缩为一行:
如果要将输入传递给进程的
stdin
,请将bytes
对象传递给input
关键字参数:您可以通过传递
stderr=subprocess.PIPE
(捕获到result.stderr
)或stderr=subprocess.STDOUT
(捕获到result.stdout
)以及常规输出来捕获错误。当不考虑安全性时,还可以通过传递shell=True
来运行更复杂的shell命令,如下面的注释所述。与以前的做事方式相比,这只增加了一点复杂性。但我认为这是值得的:现在您几乎可以只使用
run
函数做任何需要做的事情。旧版本的Python(2.7-3.4):
check_output
如果您使用的是较旧版本的Python,或者需要适度的向后兼容性,那么您可以使用上面简要描述的
check_output
函数。它从Python2.7开始就可用了。它接受与
Popen
相同的参数(见下文),并返回包含程序输出的字符串。这个答案的开头有一个更详细的用法示例。在Python 3.5及更高版本中,check_output
相当于使用check=True
和stdout=PIPE
执行run
,并只返回stdout
属性。您可以传递
stderr=subprocess.STDOUT
,以确保返回的输出中包含错误消息——但是在某些版本的Python中,传递stderr=subprocess.PIPE
到check_output
可能会导致deadlocks。当不考虑安全性时,还可以通过传递shell=True
来运行更复杂的shell命令,如下面的注释所述。如果您需要从
stderr
进行管道传输或将输入传递给进程,check_output
将无法完成任务。在这种情况下,请参见下面的Popen
示例。复杂应用程序&Python的遗留版本(2.6及以下版本):
Popen
如果您需要深入的向后兼容性,或者如果您需要比
check_output
提供的功能更复杂的功能,则必须直接使用Popen
对象,该对象封装了子流程的低级API。Popen
构造函数接受不带参数的单个命令,或接受包含命令的列表作为其第一项,后跟任意数量的参数,作为列表中的单独项。^{Popen
对象还接受一个host of different arguments用于进程IO管理和低级配置。要发送输入和捕获输出,
communicate
几乎总是首选方法。如所示:或者
如果设置了
stdin=PIPE
,communicate
还允许您通过stdin
将数据传递给进程:注意Aaron Hall's answer,这表示在某些系统上,可能需要将
stdout
、stderr
和stdin
全部设置为PIPE
(或DEVNULL
),以使communicate
完全工作。在一些罕见的情况下,您可能需要复杂的实时输出捕获。Vartec的答案表明了一条前进的道路,但是
communicate
以外的方法如果不小心使用,很容易出现死锁。与所有上述函数一样,当不考虑安全性时,可以通过传递
shell=True
来运行更复杂的shell命令。注释
1。运行shell命令:参数
shell=True
通常,对
run
、check_output
或Popen
构造函数的每个调用都执行一个单个程序。这意味着没有花哨的bash风格的管道。如果要运行复杂的shell命令,可以传递所有三个函数都支持的shell=True
。但是,这样做会提高security concerns。如果您所做的不仅仅是简单的脚本编写,那么最好分别调用每个进程,并将每个进程的输出作为输入传递给下一个进程,通过
或者
直接连接管道的诱惑力很强;抵制住它。否则,您可能会看到死锁,或者不得不做一些像this这样的讨厌的事情。
2。Unicode注意事项
check_output
在Python 2中返回一个字符串,但在Python 3中返回一个bytes
对象。如果你还没有的话,花点时间learn about unicode是值得的。像这样的:
注意,我正在将stderr重定向到stdout,这可能不是您想要的,但我也需要错误消息。
此函数在它们出现时逐行生成(通常您必须等待子流程完成才能获得完整的输出)。
对于您的情况,用法是:
这要简单得多,但只适用于Unix(包括Cygwin)和Python2.7。
它返回一个带有(return_value,output)的元组。
对于同时在Python2和Python3中工作的解决方案,请改用
subprocess
模块:相关问题 更多 >
编程相关推荐