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不阻塞運行

 

 

 

 
       


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM