之前我一直用os.system()
处理一些系统管理任务,由于我认为那是运行linux命令最简单的方式.
咱们能从Python官方文档里读到应该用subprocess
模块来运行系统命令.subprocess
模块容许咱们建立子进程,链接他们的输入/输出/错误管道,还有得到返回值。subprocess
模块打算来替代几个过期的模块和函数,好比: os.system, os.spawn*, os.popen*, popen2.*
命令。
让咱们来看一下subprocess
有哪些不一样的函数.python
执行由参数提供的命令.
咱们能够用数组做为参数运行命令,也能够用字符串做为参数运行命令(经过设置参数shell=True
)
注意,参数shell
默认为False
咱们用subprocess.call()
来作一个统计磁盘的例子:linux
subprocess.call(['df', '-h'])
下面的例子把shell
设置为True
shell
subprocess.call('du -hs $HOME', shell=True)
注意,python官方文档里对参数shell=True
陈述了一个警告:数组
Invoking the system shell with shell=True can be a security hazard if combined
with untrusted input函数
如今,咱们来看看输入与输出spa
subprocess
模块能阻止输出,当你不关心标准输出的时候是很是方便的.
它也使你经过一种正确的方式管理输入/输出,有条理地整合python脚本中的的shell命令.code
经过subprocess.call
的返回值你可以断定命令是否执行成功.
每个进程退出时都会返回一个状态码,你能够根据这个状态码写一些代码。进程
我在使用subprocess
时,有一个微妙的部分是怎么使用管道把命令链接起来.
管道代表一个新的子管道应该被建立.
默认的设置为None
,意味着没有重定向发生
标准错误能够指向标准输出,代表子进程的错误信息会被捕获到和标准输出同一个文件.ip
subprocess
模块中基本的进程建立和管理由Popen
类来处理.subprocess.popen
是用来替代os.popen
的.
咱们来作一些真实的例子,subprocess.Popen
须要一个数组做为参数:文档
import subprocess p = subprocess.Popen(["echo", "hello world"], stdout=subprocess.PIPE) print p.communicate() >>>('hello world ', None)
注意,虽然你可使用 "shell=True",但并不推荐这样的方式.
若是你知道你只用几个有限的函数,好比Popen
和PIPE
,你能够单单指定这几个函数:
from subprocess import Popen, PIPE p1 = Popen(["dmesg"], stdout=PIPE) print p1.communicate()
communicate()
函数返回一个tuple
(标准输出和错误).Popen.communicate()
和进程沟通:发送数据到标准输入.从标准输出和错误读取数据直到遇到结束符.等待进程结束.
输入参数应该是一个字符串,以传递给子进程,若是没有数据的话应该是None
.
基本上,当你用 communicate()
函数的时候意味着你要执行命令了.
subprocess
写Ping
程序咱们先问用户地址,而后用ping
请求这个地址.
# Import the module import subprocess # Ask the user for input host = raw_input("Enter a host to ping: ") # Set up the echo command and direct the output to a pipe p1 = subprocess.Popen(['ping', '-c 2', host], stdout=subprocess.PIPE) # Run the command output = p1.communicate()[0] print output