You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中如何为执行Git命令的subprocess设置超时?

subprocess配置超时的实现方案

方案1:Python 3.6 环境(原生支持timeout参数)

Python 3.5及以上版本的subprocess.run()原生提供timeout参数,单位为秒,执行超过指定时间后会主动终止子进程,并抛出subprocess.TimeoutExpired异常,可直接搭配重试逻辑使用。
修改后的代码示例(包含3次重试逻辑):

#------------------------------------------------------------------------------
#   Script to daily build Voyant 3
#------------------------------------------------------------------------------
import subprocess
import os
import time

#------------------------------------------------------------------------------
#   配置参数
#------------------------------------------------------------------------------
repo_dir = "c:/sandboxes/git/voyant-3"
MAX_RETRY = 3  # 最大重试次数
FETCH_TIMEOUT = 300  # git fetch超时时间,单位秒,此处设为5分钟

#------------------------------------------------------------------------------
#   Main program starts here.
#------------------------------------------------------------------------------
os.chdir(repo_dir)

# 带重试的git fetch逻辑
success = False
for retry_cnt in range(MAX_RETRY):
    try:
        subprocess.run(
            ["git", "fetch", "--all"],
            timeout=FETCH_TIMEOUT,
            check=True,  # 命令执行非0返回码时会抛出CalledProcessError异常
            capture_output=True,
            text=True
        )
        success = True
        break
    except subprocess.TimeoutExpired:
        print(f"git fetch 超时,第{retry_cnt+1}次重试")
    except subprocess.CalledProcessError as e:
        print(f"git fetch 执行失败,错误信息:{e.stderr},第{retry_cnt+1}次重试")
    time.sleep(10)  # 重试前等待10秒

if not success:
    print(f"git fetch 经过{MAX_RETRY}次尝试后仍失败,退出构建")
    exit(1)

# 后续构建逻辑

方案2:Python 2.7 环境(自定义超时逻辑)

Python 2.7的subprocess没有原生timeout参数,可通过subprocess.Popen配合计时轮询实现超时控制,适配Windows 10环境:

#------------------------------------------------------------------------------
#   Script to daily build Voyant 3
#------------------------------------------------------------------------------
import subprocess
import os
import time
import sys

#------------------------------------------------------------------------------
#   配置参数
#------------------------------------------------------------------------------
repo_dir = "c:/sandboxes/git/voyant-3"
MAX_RETRY = 3  # 最大重试次数
FETCH_TIMEOUT = 300  # git fetch超时时间,单位秒,此处设为5分钟

# 自定义超时异常,适配Python2.7
class TimeoutExpired(Exception):
    pass

#------------------------------------------------------------------------------
#   带超时的subprocess执行方法
#------------------------------------------------------------------------------
def run_with_timeout(args, timeout):
    proc = subprocess.Popen(args, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
    start_time = time.time()
    while proc.poll() is None:
        time.sleep(1)
        if time.time() - start_time > timeout:
            proc.kill()
            proc.wait()
            raise TimeoutExpired(f"Command {' '.join(args)} timed out after {timeout} seconds")
    stdout, stderr = proc.communicate()
    return proc.returncode, stdout, stderr

#------------------------------------------------------------------------------
#   Main program starts here.
#------------------------------------------------------------------------------
os.chdir(repo_dir)

# 带重试的git fetch逻辑
success = False
for retry_cnt in range(MAX_RETRY):
    try:
        returncode, stdout, stderr = run_with_timeout(["git", "fetch", "--all"], FETCH_TIMEOUT)
        if returncode != 0:
            print(f"git fetch 执行失败,错误信息:{stderr},第{retry_cnt+1}次重试")
            time.sleep(10)
            continue
        success = True
        break
    except TimeoutExpired as e:
        print(f"{e},第{retry_cnt+1}次重试")
        time.sleep(10)

if not success:
    print(f"git fetch 经过{MAX_RETRY}次尝试后仍失败,退出构建")
    sys.exit(1)

# 后续构建逻辑

注意事项

  • 代码中已修复原示例里["git", "fetch", "--all]"]多写的多余右括号问题
  • 超时时间可根据仓库实际大小调整,若仓库体积大、网络较慢可适当延长
  • Windows环境下注册为系统服务运行时,建议配置日志输出,方便排查超时、执行失败的原因

内容的提问来源于stack exchange,提问作者Thomas Matthews

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.13 10:03:00