0. 前提
做发布系统的时候,一开始接入的是前端发布任务,前端使用的是Node.js,是需要编译打包的,即需要npm install和npm run xxx等操作
而这两步相对来说是比较耗时的,所以使用Python在执行命令的时候,用的是subprocess库,加了超时自动断开并清理子进程的逻辑
执行命令的方法如下,超时时间默认是十分钟,为什么使用以下方法来执行命令可以参考我的另一篇文章:【命令】Python执行命令超时控制【原创】
import os
import signal
import subprocess
def run_cmd(cmd_string, timeout=600):
"""
执行命令
:param cmd_string: string 字符串
:param timeout: int 超时设置
:return:
"""
p = subprocess.Popen(cmd_string, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, shell=True, close_fds=True,
start_new_session=True)
format = 'utf-8'
if platform.system() == "Windows":
format = 'gbk'
try:
(msg, errs) = p.communicate(timeout=timeout)
ret_code = p.poll()
if ret_code:
code = 1
msg = "[Error]Called Error : " + str(msg.decode(format))
else:
code = 0
msg = str(msg.decode(format))
except subprocess.TimeoutExpired:
# 注意:不能使用p.kill和p.terminate,无法杀干净所有的子进程,需要使用os.killpg
p.kill()
p.terminate()
os.killpg(p.pid, signal.SIGUSR1)
# 注意:如果开启下面这两行的话,会等到执行完成才报超时错误,但是可以输出执行结果
# (outs, errs) = p.communicate()
# print(outs.decode('utf-8'))
code = 1
msg = "[ERROR]Timeout Error : Command '" + cmd_string + "' timed out after " + str(timeout) + " seconds"
except Exception as e:
code = 1
msg =