Python系列 49 内置模块:subprocess

subprocess简介

subprocess模块最早在Python2.4中引入,它会生成一个子进程,该子进程可以执行shell命令,并且会监听系统的标准输入管道、标准输出管道、标准错误管道,在命令执行完毕后,将结果进行返回到对应的管道中。

官方文档

如下图所示:

image-20210527190008666

它的功能虽然看上去十分单一,但是应用是非常广泛的。

试想,你是一名运维人员,编写了1个脚本,每天定时定点的在100台机器上获得它们的状态信息,就可以用到该模块。

让脚本在宿主机上通过该模块执行命令,并且拿到命令的返回结果,再通过网络返回结果并对其进行分析,依此判定各个宿主机的工作状态。

简单的使用

对于简单的使用,记住这4个方法即可,如下表所示:

方法描述
subprocess.Popen(…)执行系统命令,并将执行结果放入对应的管道中,返回一个Popen对象
PopenObject.stdout.read()从标准输出管道中获取执行结果
PopenObject.stderr.read()从标准错误管道中获取执行结果
PopenObject.stdin.write()通过标准输入管道与系统进行交互

subprocess.Popen()的可指定参数比较多,下面是它的签名:

    def __init__(self, args, bufsize=-1, executable=None,
                 stdin=None, stdout=None, stderr=None,
                 preexec_fn=None, close_fds=_PLATFORM_DEFAULT_CLOSE_FDS,
                 shell=False, cwd=None, env=None, universal_newlines=False,
                 startupinfo=None, creationflags=0,
                 restore_signals=True, start_new_session=False,
                 pass_fds=(), *, encoding=None, errors=None):

常用参数的释义如下:

  • args:将要执行的命令,可以是str类型或者list、tuple类型
  • bufsize:指定缓冲大小,0是没有,1是默认
  • executable:要执行的替换程序
  • stdin/stdout/stderr:标准输入、输出、错误管道的句柄
  • preexec_fn:仅在Unix平台下有效。指定一个可调用对象,通常是指函数,它将在fork出的子程序运行之前调用
  • close_sds:在Windows平台下,如果该参数指定为True,则fork出的子程序将不会继承父程序的标准输入、输出、错误管道中传输的内容,一般设置默认即可
  • shell:如果为True,则通过shell执行命令
  • cwd:设置子进程执行时的工作目录
  • env:用于指定子进程的环境变量,如果为None,子进程将继承父进程的环境变了
  • Universal_newlines:如果为True,则不区分平台,统一将换行符定义为\n

简单的执行命令并获取返回结果:

import subprocess

popenObject = subprocess.Popen(
    args="ping www.baidu.com",
    shell=True,
    stdin=subprocess.PIPE,
    stderr=subprocess.PIPE,
    stdout=subprocess.PIPE,
)

successMessage, errorMessage = popenObject.stdout.read(), popenObject.stderr.read()
print(successMessage.decode("gbk"))
print(errorMessage.decode("gbk"))

popenObject.stdout.close()
popenObject.stderr.close()

注意事项:

  • 如果你的测试环境是Windows,则对执行结果的解码方式需要使用GBK,因为Windows的终端字符编码方式就是GBK。而如果是Unix平台只需要使用UTF8即可。

通过stdin与与宿主机进行交互:

import subprocess

# 执行的语句
stdInCommand = """print (\"Hello, world\")"""

# 通过subprocess在测试机上启动1个新的Python REPT交互式环境
popenObject = subprocess.Popen(
    args="python",
    shell=True,
    stdin=subprocess.PIPE,
    stderr=subprocess.PIPE,
    stdout=subprocess.PIPE,
    )

# 写入内容,进行交互,注意每次交互完毕后都要立即关闭管道
popenObject.stdin.write(stdInCommand.encode("utf8"))
popenObject.stdin.close()

# 获取并打印结果
successMessage, errorMessage = popenObject.stdout.read(), popenObject.stderr.read()
print(successMessage.decode("gbk"))
print(errorMessage.decode("gbk"))

popenObject.stdout.close()
popenObject.stderr.close()

更多的操作

以下方法了解即可,其实用的并不多:

方法描述
subprocess.run()执行命令,不返回结果,拥有timeout参数,可设定超时时间
subprocess.call()执行命令,并且返回执行状态(bool类型,0成功,1失败)
subprocess.check_call()执行命令,并且返回执行结果和执行状态,如果命令执行失败则抛出异常,
subprocess.getstatusoutput()执行命令,返回1个tuple,[0]是执行状态,[1]是执行结果
subprocess.getoutput()执行命令,返回执行结果(str类型)
subprocess.check_output()执行命令,返回执行结果(bytes类型)

这里就不再进行演示了,感兴趣的可以参见官方文档。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值