Python ---- Subprocess模块原理

其实有一个模块也支持执行系统命令,那个模块就是sys.system,但他执行系统命令会直接通过主进程去执行命令,那假如,该命令的执行需要耗费一个小时,那么主进程会卡一个小时,而不会去干别的事,这样就会导致程序的运行效率低下。

如果由subprocess去执行系统命令的时候并不会让主进程去执行,而是主进程会开辟出一个子进程去执行,并不会影响到主进程的运行,主进程该干嘛就干嘛,那么又有个问题,大家都知道进程之间的内存空间是独立的,也就是说进程之间是不能相互访问的,那么在subprocess中,有个管道的概念,既然固定死了进程之间不能相互访问,那么可以将执行命令的结果输出到管道里,该管道其实就是一块共享的内存空间,可以让主进程去获取到该共享内存空间存放的数据。

在这里插入图片描述
实例 : 用一个子进程来执行命令

import subprocess

obj = subprocess.Popen('systeminfo',  # 执行系统命令(必须是字符串的格式)
                       shell=True,  # 指定命令解释器来执行这条命令
                       stdout=subprocess.PIPE,  # 将执行的正确结果丢到管道(共享空间,用于进程之间的共享)
                       stderr=subprocess.PIPE,  # 将执行的错误结果丢到另一个新的管道
                       )
# 取出正确的结果
res1 = obj.stdout.read()  # 主进程去管道里获取正确的结果
print(res1.decode('gbk'))  # 获取的结果是 bytes 类型,需要指定decode指定编码

# 取出错误的管道中的结果
res2 = obj.stderr.read()
print(res2.decode('utf-8', 'ignore'))

Subprocess 模块其他参数说明
subprocess.Popen(args,
bufsize=0,
executable=None,
stdin=None,
stdout=None,
stderr=None,
preexec_fn=None,
close_fds=False,
shell=False,
cwd=None,
env=None,
universal_newlines=False,
startupinfo=None,
creationflags=0))

args 参数,可以是一个字符串,也可以是一个包含程序参数的列表,要执行的程序一般就是这个列表的第一项,或者是字符串本身。
如果 args是一个列表,则第一项被视为命令,其余的视为给shell 本身的参数。

subprocess.Popen([“cat”,“test.txt”])
subprocess.Popen(“cat test.txt”)

这两个之中,后者将不会工作。因为如果是一个字符串的话,必须是程序的路径才可以。(考虑unix的api函数exec,接受的是字符串
列表)
后者要执行的话需要指定参数 shell = True 即:

subprocess.Popen(“cat test.txt”, shell=True)

shlex.split()可以被用于序列化复杂的命令参数,比如:

>>> shlex.split('ls ps top grep pkill')
['ls', 'ps', 'top', 'grep', 'pkill']

stdin stdout和stderr:
stdin stdout和stderr,分别表示子程序的标准输入、标准输出和标准错误。可选的值有PIPE或者一个有效的文件描述符(其实是个正
整数)或者一个文件对象,还有None。如果是PIPE,则表示需要创建一个新的管道,如果是None
,不会做任何重定向工作,子进程的文件描述符会继承父进程的。另外,stderr的值还可以是STDOUT
,表示子进程的标准错误也输出到标准输出。

其他相关的命令
1、subprocess.call
subprocess.call (*popenargs , **kwargs )
执行命令,并等待命令结束,再返回子进程的返回值。参数同Popen。

2、subprocess.check_call
subprocess.check_call (*popenargs , **kwargs )
执行上面的call命令,并检查返回值,如果子进程返回非0,则会抛出CalledProcessError异常,这个异常会有个returncode
属性,记录子进程的返回值。

3、Popen 对象说明
在这里插入图片描述

参考博客链接:subprocess.Popen()详解

当使用Python的logger模块subprocess模块时,可能会遇到卡死的问题。在处理这个问题之前,首先要了解logger和subprocess的工作原理。 logger模块Python标准库中的一个模块,用于记录日志信息。它能够将日志信息输出到控制台、文件或其他地方。它提供了丰富的功能和配置选项,可以方便地记录和管理日志。 subprocess模块是用于创建子进程的模块。它能够执行外部命令,并与其交互。它提供了多种执行外部命令的方式,并且可以捕获命令的输出和错误信息。 在使用logger和subprocess模块时,可能会出现卡死的情况。这种情况通常是由于子进程没有正确地被销毁所导致的。一种可能的原因是子进程在执行命令时发生了错误,但是错误没有被捕获到,从而导致子进程没有被正确地销毁。当这种情况发生时,主进程可能会一直等待子进程结束,从而导致卡死。 解决这个问题的方法是,在创建子进程之前,先设置subprocess模块的相关参数,例如设置子进程的超时时间和错误处理方式。当子进程执行超过设定的时间或者发生错误时,会自动中断子进程,并抛出异常。通过捕获这些异常,可以及时处理子进程的错误,避免卡死的情况发生。 另外,还可以在logger模块中设置超时参数,以避免在记录日志时发生卡死。当logger执行的操作超过设定的时间时,可以选择中断操作,并抛出异常。 综上所述,解决Python logger subprocess卡死的问题需要设置合适的超时参数和异常处理方式,以及及时捕获并处理子进程和logger模块的异常。这样可以保证程序的稳定性和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值