subprocess模块
一、python执行命令方法
1、os.system()
os.system()的返回值是脚本的退出状态码,0表示成功; 其他均为失败
执行命令出错,并不会影响主进程执行
res = os.system('ls')
print(res) # 0
res = os.system('dddd')
print(res) # 32512
print(os.system('ls'))
print(os.system('ddd'))
print(111)
0
32512
111
2、subprocess模块
1)subprocess包提供了三个开启子进程的方法:
subprocess.call()
subprocess.check_call()
subprocess.check_output()
2)三种方法区别在于返回结果不同:
call()
返回子进程的执行返回码check_call()
返回子进程的执行返回码的处理结果,返回码是0则返回0,否则出错的话会raise CalledProcessErrorcheck_output()
返回码是0则返回子进程向stdout输出的结果,否则也raise CalledProcessError
3)传递命令字符串作为参数,可以用以下两种形式
- 列表形式:
['ping','www.baidu.com','-c','3']
- 字符串形式:
"ping www.baidu.com -c 3"
4)在开启子进程的时候,可以加上shell=True
的参数来让python开启一个shell,通过shell来解释获得的命令。
- 一般在windows下运行的程序最好都把
shell=True
加上,这样才能顺利地执行dos命令 - 在linux下似乎不加也没啥关系。因为linux下未指明用shell执行的话会调用
/bin/sh
来执行,但是dos下系统不会默认用cmd.exe来执行命令,所以要加上shell=True。
5)这三个方法都是对subprocess.Popen
方法的一个包装,让父进程挂起等待的,在子进程结束之前,父进程不会继续往下运行。
6)subprocess.Popen()
方法不会让父进程等待其完成的, 如要父进程等待子进程,必须调用wait()
方法
二、subprocess.Popen()方法
subprocess.Popen(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: 字符串或列表
stdin, stdout and stderr: None->继承父进程;PIPE->创建管道; 等等
preexec_fn: (POSIX only) 在创建(fork)和执行(exec)之间执行
shell: unix相当于在args前面添加"/bin/bash -c";widows下相当于添加"cmd.exe /c"
cwd: 设置shell执行的工作目录
env: 设置环境变量,默认为None,默认继承父进程的环境变量
Attributes:
stdin, stdout, stderr, pid, returncode
"""
1、常用参数详解
-
stdin, stdout and stderr
输入、输出、错误,既可以输出到PIPE中,也可以输出到文件中,注意PIPE爆满导致卡死,
communicate()
可解决:https://www.cnblogs.com/linagcheng/p/15352648.html -
preexec_fn
详见:https://www.cnblogs.com/linagcheng/p/15597279.html
接受一个回调函数,并在
fork
之后exec
之前的间隙中执行它应用:执行
os.setsid()
成立一个独立的进程组,通过向进程组发送SIGTERM
或SIGKILL
来kill subprocess中的所有子孙进程 -
start_new_session
为True时,新建一个进程组,并以当前进程为master进程,一旦向该进程组发送
SIGTERM
或SIGKILL
,便可kiil subprocess中的所有子孙进程功能与
preexec_fn=os.setsid()
类似 -
shell
unix相当于在args前面添加
/bin/bash -c
;widows下相当于添加cmd.exe /c
-
env
用于指定子进程的环境变量,如果env=None(默认),那么子进程的环境变量将从父进程中继承。如果env!=None,它的值必须是一个映射对象。
-
cwd
设置shell执行的工作目录
三、在一个shell中执行多条命令
方式一:
创建一个shell,通过stdin.write()
来不断执行命令
之一每个命令多要用utf-8
编码, \n
结尾表示模拟回车执行命令
p = subprocess.Popen("/bin/bash", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
p.stdin.write('chmod +x /data/start.sh\n'.encode('utf-8'))
p.stdin.write('cd /data\n'.encode('utf-8'))
p.stdin.write('./start.sh\n'.encode('utf-8'))
p.stdin.close()
p.wait()
方式二:
将多条命令整合到一条中,然后执行
p = subprocess.Popen('chmod +x /data/start.sh && cd /data && ./start.sh', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()
四、returncode
None —— 子进程尚未结束;
==0 —— 子进程正常退出;
> 0 —— 子进程异常退出,returncode对应于出错码;
< 0 —— 子进程被信号杀掉了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix