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

Python subprocess调用Genymotion重启命令超时,手动执行正常

问题排查:Python调用gmtool重启Genymotion设备超时

问题描述

我编写了以下Python函数用于重启Genymotion设备:

def restart_device(d, stop_timeout=40, start_timeout=30):
    """Restarts a specific Genymotion device with timeouts and logs the process."""
    try:
        device_name = get_device_name_by_ip(d.serial)
        logging.info(f"Stopping device: {device_name}")
        subprocess.run([gmtoolPath, "admin", "stop", device_name], check=True, timeout=stop_timeout)
        time.sleep(5)  # Wait a bit before restarting

        logging.info(f"Starting device: {device_name}")
        subprocess.run([gmtoolPath, "admin", "start", device_name], check=True, timeout=start_timeout)

        # Wait for the device to boot up
        logging.info(f"Waiting for device {device_name} to boot...")
        time.sleep(30)  # Adjust the wait time as needed
        logging.info(f"Device {device_name} restarted successfully.")
    except subprocess.CalledProcessError as e:
        logging.error(f"Error restarting device {device_name}: {e.stderr}")
    except subprocess.TimeoutExpired as e:
        logging.error(f"Timeout expired while restarting device {device_name}: {e}")

执行该函数时会触发超时,但手动在终端运行对应的gmtool admin stop <device_name>和gmtool admin start <device_name>命令完全正常,且另一台电脑上运行相同代码无异常。

排查方向与解决方案

1. 环境变量差异

手动执行终端的环境变量和Python进程的环境变量可能不一致,尤其是gmtoolPath的路径是否正确,或是gmtool依赖的系统路径未在Python进程中配置。可在代码中打印对比:

import os
print(os.environ["PATH"])
print(gmtoolPath)

确认gmtool的完整路径是否正确,也可以在subprocess调用中直接指定gmtool的绝对路径,避免依赖环境变量。

2. 子进程输出阻塞

subprocess.run默认会捕获stdout和stderr,若gmtool执行时产生大量输出,可能导致缓冲区阻塞进而触发超时。可修改调用方式重定向输出:

# 丢弃输出
subprocess.run(
    [gmtoolPath, "admin", "stop", device_name],
    check=True,
    timeout=stop_timeout,
    stdout=subprocess.DEVNULL,
    stderr=subprocess.STDOUT
)

或写入日志文件:

with open("gmtool_exec_log.txt", "a") as f:
    subprocess.run(
        [gmtoolPath, "admin", "stop", device_name],
        check=True,
        timeout=stop_timeout,
        stdout=f,
        stderr=f
    )

3. 运行权限差异

Python进程的运行权限与手动执行终端的权限可能不同,比如是否有访问Genymotion设备目录、虚拟设备文件的权限,或是是否以管理员身份运行。尝试以相同权限运行Python脚本(比如手动终端用普通用户,脚本也用该用户运行;或都用管理员权限)。

4. 超时时间调整

不同机器性能有差异,当前设置的超时时间可能不足以支撑本地设备的启停操作。可临时调大stop_timeout和start_timeout的值(比如设为60秒),测试是否还会超时。若调大后正常,说明本地机器需要更长的执行时间。

5. 设备状态预检查

执行stop命令前,先调用gmtool admin list获取设备状态,确认设备处于可停止状态再执行操作,避免因设备异常导致stop命令耗时过长。

内容的提问来源于stack exchange,提问作者Achiya Ben Natan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:25:06