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

如何让Python脚本在Screen会话中自动重启自身?

实现Python脚本自动检测并切换到Screen会话运行

核心思路

Screen会话会自动设置STY环境变量,我们可以通过检测这个变量判断脚本是否在Screen中运行;如果不在,就用os.execvp替换当前进程,启动Screen会话并在其中重新运行脚本。

完整实现代码

import os
import sys

def is_in_screen():
    # 检测STY环境变量,存在则说明处于Screen会话
    return 'STY' in os.environ

def restart_in_screen():
    # 获取当前Python解释器路径,避免硬编码导致环境不一致
    python_exec = sys.executable
    # 构造Screen命令参数:
    # -D -m:强制启动分离式会话,断开连接后脚本仍能后台运行
    # -S:指定会话名称,方便后续用screen -r 重新连接
    screen_cmd = [
        'screen',
        '-D', '-m',
        '-S', 'long_running_script',
        python_exec
    ] + sys.argv  # 传递原脚本的所有启动参数

    # 替换当前进程为Screen命令,原脚本进程会终止
    os.execvp('screen', screen_cmd)

if __name__ == '__main__':
    if not is_in_screen():
        print("不在Screen会话中,将重启到Screen运行...")
        restart_in_screen()
    
    # ---------------------- 以下是你的业务代码 ----------------------
    print("已在Screen会话中运行,开始执行长时间任务")
    import time
    for count in range(100):
        print(f"任务进度: {count+1}/100")
        time.sleep(1)

关键细节说明

  1. 检测Screen会话的正确方式
    不要用解析进程树的方式,直接读取STY环境变量是Screen官方推荐的检测方法,简单可靠。

  2. 为什么用os.execvp而不是subprocess

    • os.execvp会直接替换当前脚本进程,不会留下额外的父进程,避免出现脚本重复运行的问题;
    • subprocess.run会创建子进程,原脚本进程仍会继续执行,可能导致逻辑混乱。
  3. Screen参数的作用

    • -D -m:强制启动一个分离的Screen会话,即使当前已经有其他会话存在,也能确保脚本在后台稳定运行;
    • -S long_running_script:自定义会话名称,后续可以用screen -r long_running_script快速重新连接查看输出。
  4. 参数传递的正确性

    • 用sys.executable获取当前Python解释器路径,避免硬编码python/python3导致的环境差异;
    • 直接拼接sys.argv保留所有原启动参数,确保重启后的脚本和原调用逻辑一致。

你之前写法的问题

  • 使用subprocess.run(..., shell=True)时,列表格式的参数会被当作单个字符串传递给shell,导致Screen无法正确解析命令;
  • os.execv的参数构造错误:你把python + " " + sys.argv[0]作为单个参数传递,Screen会把这个整串当作一个命令去执行,而不是拆分出Python解释器和脚本路径,自然无法运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:55:29