以前我一直用os.system()
处理一些系统管理任务,因为我认为那是运行linux命令最简单的方式.
subprocess
模块来运行系统命令.subprocess
模块允许我们创建子进程,连接他们的输入/输出/错误管道,还有获得返回值。subprocess
模块打算来替代几个过时的模块和函数,比如: os.system, os.spawn*, os.popen*, popen2.*
命令。让我们来看一下subprocess
有哪些不同的函数. subprocess.call()
执行由参数提供的命令.
我们可以用数组作为参数运行命令,也可以用字符串作为参数运行命令(通过设置参数shell=True
)注意,参数shell
默认为False
我们用subprocess.call()
来做一个统计磁盘的例子: subprocess.call(['df', '-h'])
下面的例子把shell
设置为True
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
现在,我们来看看输入与输出
Input and Output
subprocess
模块能阻止输出,当你不关心标准输出的时候是非常方便的.
Return Codes
通过subprocess.call
的返回值你能够判定命令是否执行成功.
stdin, stdout and stderr
我在使用subprocess
时,有一个微妙的部分是怎么使用管道把命令连接起来.
None
,意味着没有重定向发生标准错误可以指向标准输出,表明子进程的错误信息会被捕获到和标准输出同一个文件. subprocess.Popen()
subprocess
模块中基本的进程创建和管理由Popen
类来处理.
subprocess.popen
是用来替代os.popen
的.我们来做一些真实的例子,subprocess.Popen
需要一个数组作为参数: import subprocessp = subprocess.Popen(["echo", "hello world"], stdout=subprocess.PIPE)print p.communicate()>>>('hello world', None)
注意,虽然你可以使用 "shell=True",但并不推荐这样的方式.
如果你知道你只用几个有限的函数,比如Popen
和PIPE
,你可以单单指定这几个函数: from subprocess import Popen, PIPEp1 = Popen(["dmesg"], stdout=PIPE)print p1.communicate()
Popen.communicate()
communicate()
函数返回一个tuple
(标准输出和错误).
Popen.communicate()
和进程沟通:发送数据到标准输入.从标准输出和错误读取数据直到遇到结束符.等待进程结束.输入参数应该是一个字符串,以传递给子进程,如果没有数据的话应该是None
.基本上,当你用 communicate()
函数的时候意味着你要执行命令了. 用subprocess
写Ping
程序
我们先问用户地址,然后用ping
请求这个地址.
# Import the moduleimport subprocess# Ask the user for inputhost = raw_input("Enter a host to ping: ") # Set up the echo command and direct the output to a pipep1 = subprocess.Popen(['ping', '-c 2', host], stdout=subprocess.PIPE)# Run the commandoutput = p1.communicate()[0]print output