python执行cmd命令 python创建子进程

项目需求描述:

1.第一阶段:首先有一个本地机器人项目有个Bot进程负责接收服务端的任务,并执行

2.第二阶段:服务端想要控制Bot的启动停止,并且监控状态,机器人项目就加了个Bot_Runner主进程产生Bot子进程,Bot_Runner主进程监听服务端的卡夫卡服务器接受任务操作Bot子进程,从而实现服务端对Bot的控制

  1)python执行cmd命令创建并控制子进程

  2)python使用卡夫卡

  3)pipenv 代替pip管理项目

3.第三阶段:Bot_Runner主进程和Bot子进程的代码更新后,需要登录每台云服务器去升级代码安装一堆依赖,太麻烦,就做了一个git_helper项目,通过卡夫卡接收服务端clone/pull命令,对机器人项目进行远程更新

  1)python操作git

  2)python杀死无关的python进程

  3) python删除文件夹

4.第四阶段: git_helper项目虽然可以更新机器人代码,但是这个项目还是要手动clone安装依赖什么的,这个活也挺麻烦,就想把git_helper项目的 clone+依赖安装+启动 做成windows服务,开机自启,搞来搞去各种出错就放弃做成服务,做成了个exe,双击就好了

  1)python打包程序为exe

 

这个流程下来会频繁执行cmd命令,就总结一下python执行cmd命令的方式:

一、python使用subprocess执行cmd命令创建进程

特点:

1.subprocess.Popen创建的子进程随主进程结束而终止(好像是,记不太清楚了,懒得试,哈哈哈)

2.可以通过popen获得子进程运行状态,并且控制子进程

详见:subprocess创建子进程,subprocess执行py脚本文件,subprocess使用pipenv管理的虚拟环境执行子进程

二、python使用os.syetem执行cmd命令创建进程

特点:

system 函数可以将字符串转化成命令在服务器上运行

其原理是每一条 system 函数执行时,其会创建一个子进程在系统上执行命令行,子进程的执行结果无法影响主进程。
system创建的子进程运行不依赖于主进程,主进程结束子进程也能正常运行

 

根据切换盘符方式不同,执行多条语句有不同的语法,如下:

2.1 os.seytem

(1)os.seytem直接cd切换

# 第一种 os.system执行cd命令切换子进程盘符,执行其他文件
# 当前目录D:\gittest,要再D:/gittest/代码/weebot_wxbot目录中安装依赖,并启动666.py
os.system('cd ..') # 这个只能改变os创建的子进程的目录,不能改变当前主进程工作目录
print(os.getcwd()) # 还是当前目录D:\gittest
# 所以用os.system执行cd命令切换盘符的,只能一气呵成用 && 或者 ; 来拼接执行命令,不能分步执行
os.system('cd ../代码/weebot_wxbot && pipenv install && start pipenv run python 666.py')# 在 cmd 命令前加入 start 可不阻塞当前程序执行
# os.system('cd ../代码/weebot_wxbot ; pipenv install ; start pipenv run python 666.py')

(2)os.seytem切换到C盘,有些操作系统不能直接,切换需要特殊处理

后来发现可能是反斜杠造成的,可以使用:

C:\/WEEBOT/wibot_bot/bot.exe
# Windows中文家庭版 2010 :不能直接cd到C盘++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
res = os.system(r"cd D:\ && dir")  # 这样是ok的,dir显示是D盘
# res = os.system(r"cd C:\BR_autoupdate\AutoUpdate && dir") # dir显示还是当前盘符,切换失败
res = os.system(r"C: && cd BR_autoupdate\AutoUpdate && dir")  # 这样就对了
print(res)  # 0/1 0表示执行正常,不代表执行成功
# res = os.system(r"C: && cd BR_autoupdate\AutoUpdate && start AutoUpdate.exe http://127.0.0.1"") #执行exe成功

# windows server 2019 英文版: 服务器版本可以直接cd到C盘+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# res = os.system(r"cd C:\BR_autoupdate\AutoUpdate && start AutoUpdate.exe http://127.0.0.1"") # windows server 2019

# 如果可以用相对路径的话两个系统都可以用++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
res = os.system(r"start ..\AutoUpdate\AutoUpdate.exe http://127.0.0.1"")
print(res)

 

2.2 os.chdir切换盘符

# 第二种os.chdir切换主进程盘符,执行其他文件
base_path = os.getcwd() # 获取当前主进程基础目录
os.chdir('../代码/weebot_wxbot_bieyang') # 这个可以改变当前主进程工作目录到指定的路径
print(os.getcwd()) # D:\代码\weebot_wxbot,主进程目录已经变化

os.system('pipenv install') # 默认阻塞当前程序执行依赖安装
aa = os.system('start pipenv run python 666.py') # 在 cmd 命令前加入 start 可不阻塞当前程序执行
# os.system('pipenv install && start pipenv run python 666.py') # 可以分开执行也可以这样

os.chdir(base_path) # 更新并启动后从子进程的工作目录再次切回当前主进程基础目录

 2.3 python杀死进程

# taskkill /f /t /im Wechat.exe   taskkill更多参数可以百度
# /f 指定将强制终止的进程  /t终止指定的进程与该进程启动的任何子进程  /im 表示指定的进程名称,例如“explor.exe"

# 第一种 os的方法
os.system(f"taskkill /t /f /pid {self.wx_pid}")
os.system(f"taskkill /t /f /im Wechat.exe")

# 第二种 使用subprocess的方法
subprocess.run(['taskkill', '/f', '/t', '/im', 'WeChat.exe'])

 2.4 python启动exe   os.system打开程序路径有空格 os.system切换路径到C盘

1)常规来说 使用os.system(r'../wechat/Wechat.exe'),是可以的,但是当路径中有空格时就会出错,如下:

import os
cmd = "start D:\Program Files\Tencent\QQ\Bin\QQScLauncher.exe"
os.system(cmd)

 

可以这样执行:

# 第一种
subprocess.Popen(r'C:\Program Files (x86)\Tencent\WeChat\WeChat.exe') # 不阻塞
# 第二种
os.chdir(r'C:\Program Files (x86)\Tencent\WeChat') # 注意:会改变运行主目录的
print(os.getcwd())  # 当前运行目录改变为:C:\Program Files (x86)\Tencent\WeChat
os.system('start WeChat.exe') # 加start不阻塞运行

 

 

 


posted @ 2021-09-30 16:25  www.pu  Views(1664)  Comments(0Edit  收藏  举报