Python subprocess模块核心用法与参数详解
本文深入解析Python中subprocess模块的核心用法,详细对比run、call、check_call等常用方法的差异与适用场景。重点讲解subprocess.Popen的高级参数配置,包括stdin/stdout管道处理、超时控制及信号管理,并提供完整的代码案例与信号总结,帮助开发者高效进行进程控制。
简介
subprocess模块用于启动新进程,并通过连接其输入、输出和错误管道来与这些进程交互,从而获取执行结果。
常用方法和接口
1、subprocess.run()
2、subprocess.call()
3、subprocess.check_call()
4、subprocess.getstatusoutput()
5、subprocess.getoutput()
6、subprocess.check_output()
7、subprocess.Popen()
subprocess.run()解析
常用参数:
- args:指定要执行的命令,可以是字符串或字符串列表。
- stdin、stdout 和 stderr:定义子进程的标准输入、输出和错误流。这些值可以是 subprocess.PIPE(创建新管道)、subprocess.DEVNULL(使用 /dev/null)、已存在的文件描述符、已打开的文件对象或 None(默认,不做处理)。此外,stderr 可以合并到 stdout 中一同输出。
- timeout:设置命令执行的超时时间。若超时,子进程将被终止,并抛出 TimeoutExpired 异常。
- check:若设为 True,且进程退出状态码非 0,则抛出 CalledProcessError 异常。
- encoding:若指定此参数,stdin、stdout 和 stderr 可接收字符串数据,并按指定编码处理;否则仅接收 bytes 类型数据。
- shell:若为 True,则通过操作系统的 shell 执行指定命令。
subprocess.Popen()解析
Popen 是 subprocess 的核心类,负责子进程的创建与管理。
常用参数:
args:shell 命令,可以是字符串或序列类型(如 list、元组)。
bufsize:缓冲区大小,仅在创建标准流管道对象时有效,默认值为 -1。
0:不使用缓冲区。
1:表示行缓冲,仅在 universal_newlines=True(文本模式)时可用。
正数:表示缓冲区大小。
负数:表示使用系统默认的缓冲区大小。
stdin, stdout, stderr:分别指定子进程的标准输入、输出和错误句柄。
preexec_fn:仅在 Unix 平台下有效,指定一个在子进程运行前调用的可调用对象。
shell:若为 True,则通过操作系统的 shell 执行指定命令。
cwd:用于设置子进程的当前工作目录。
env:用于指定子进程的环境变量。若 env 为 None,子进程将继承父进程的环境变量。
Popen 对象方法
- poll():检查进程是否终止,若终止返回 returncode,否则返回 None。
- wait(timeout):等待子进程终止。
- communicate(input,timeout):与子进程交互,发送和读取数据。
- send_signal(singnal):向子进程发送信号。
- terminate():停止子进程,即向子进程发送 SIGTERM 信号。
- kill():杀死子进程,即向子进程发送 SIGKILL 信号。
subprocess.run()案例
import subprocess
print(subprocess.run(["pip", "list"]))subprocess.call()案例
执行命令,返回命令的结果和执行状态,0或者非0
import subprocess
result1 = subprocess.call(["pip", "list"])
print("*" * 30)
print(result1) # 0
result2 = subprocess.call(["pip", "list1"])
print("*" * 30)
print(result2) # -1
# 运行结果
# ******************************
# 0
# ERROR: unknown command "list1" - maybe you meant "list"
# ******************************
# 1subprocess.check_call()案例
执行命令,返回结果和状态,正常为0 ,执行错误则抛出异常
import subprocess
result1 = subprocess.check_call(["pip", "list"])
print("*" * 30)
print(result1)
result2 = subprocess.check_call(["pip", "list2"])
print("*" * 30)
print(result2)
# 运行结果,运行错误,抛出异常。
# ******************************
# 0
# raise CalledProcessError(retcode, cmd)
# subprocess.CalledProcessError: Command '['pip', 'list2']' returned non-zero exit status 1.subprocess.getstatusoutput()案例
接受字符串形式的命令,返回 一个元组形式的结果,第一个元素是命令执行状态,第二个为执行结果。
import subprocess
result1 = subprocess.getstatusoutput("pip --version")
print(result1)
# 返回:第一个元素0, 第二个为执行结果
# (0, 'pip 21.1.3 from C:\\lib\\site-packages\\pip (python 3.9)\n')
result2 = subprocess.getstatusoutput("pip -vesi")
print(result2)
# 执行失败的案例
# (2, '\nUsage: \n pip <command> [options]\n\nno such option: -e')subprocess.getoutput()案例
接受字符串形式的命令,放回执行结果
import subprocess
result1 = subprocess.getoutput("pip --version")
print(result1)
# 返回
# pip 21.1.3 from D:\\lib\site-packages\pip (python 3.9)
result2 = subprocess.getoutput("pip -vesi")
print(result2)
# 返回
# Usage:
# pip <command> [options]
#
# no such option: -esubprocess.check_output()案例
执行命令,返回执行的结果,而不是打印
import subprocess
result1 = subprocess.check_output("pip --version")
print(result1)
# 返回
# b'pip 21.1.3 from D:\\lib\\site-packages\\pip (python 3.9)\r\r\n'
result2 = subprocess.check_output("pip -vesi")
print(result2)
# 返回
# raise CalledProcessError(retcode, process.args,
# subprocess.CalledProcessError: Command 'pip -vesi' returned non-zero exit status 2.subprocess.Popen()综合案例
案例中视频长度代码,请参考 - Python:获取视频时长 - 实践场景
# coding:utf-8
import time
import datetime
import subprocess
from analysis_video import video_duration
file = r"C:\Users\videos\duck.mp4" # 请根据实际情况填写视频路径
video_time = video_duration(file)
print(video_time)
video_pid = subprocess.Popen(f'C:\Program Files\Windows Media Player\wmplayer.exe {file}')
# poll(): 检查进程是否终止,如果终止返回 returncode,否则返回 None。
print(f"now:{datetime.datetime.now()}. - 当前返回状态:{video_pid.poll()}")
# now:2021-11-28 11:20:48.504796. - 当前返回状态:None
# 获取当前执行子shell的程序的进程号
print("当前执行进程号为:{}".format(video_pid.pid))
sleeps = int(video_time) + 2
print(f"根据视频时长等待:{sleeps}秒")
time.sleep(sleeps)
# kill(): 杀死子进程。发送 SIGKILL 信号到子进程。
video_pid.kill()
time.sleep(1)
print(f"now:{datetime.datetime.now()}. - 当前返回状态:{video_pid.poll()}")
# now:2021-11-28 11:21:05.520822. - 当前返回状态:1
# wait()
# 等待命令执行完成,并且返回结果状态
print(video_pid.wait()) # 1运行结果:

附,各种信号总结
SIGHUP 终止进程 终端线路挂断 SIGINT 终止进程 中断进程 SIGQUIT 建立CORE文件终止进程,并且生成core文件 SIGILL 建立CORE文件 非法指令 SIGTRAP 建立CORE文件 跟踪自陷 SIGBUS 建立CORE文件 总线错误 SIGSEGV 建立CORE文件 段非法错误 SIGFPE 建立CORE文件 浮点异常 SIGIOT 建立CORE文件 执行I/O自陷 SIGKILL 终止进程 杀死进程 SIGPIPE 终止进程 向一个没有读进程的管道写数据 SIGALARM 终止进程 计时器到时 SIGTERM 终止进程 软件终止信号 SIGSTOP 停止进程 非终端来的停止信号 SIGTSTP 停止进程 终端来的停止信号 SIGCONT 忽略信号 继续执行一个停止的进程 SIGURG 忽略信号 I/O紧急信号 SIGIO 忽略信号 描述符上可以进行I/O SIGCHLD 忽略信号 当子进程停止或退出时通知父进程 SIGTTOU 停止进程 后台进程写终端 SIGTTIN 停止进程 后台进程读终端 SIGXGPU 终止进程 CPU时限超时 SIGXFSZ 终止进程 文件长度过长 SIGWINCH 忽略信号 窗口大小发生变化 SIGPROF 终止进程 统计分布图用计时器到时 SIGUSR1 终止进程 用户定义信号1 SIGUSR2 终止进程 用户定义信号2 SIGVTALRM 终止进程 虚拟计时器到时

以上就是一文搞懂Python中subprocess模块的使用的详细内容,更多关于Python subprocess模块的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









