如何在Python方法中启动Screen会话并使其永久运行?
解决Python启动Screen会话后持续运行的问题
你的代码核心问题是没有用Screen的后台分离模式启动,同时错误依赖stdin管道传递命令,导致父进程退出后Screen会话跟着关闭。以下是具体的修复方案和解释:
核心问题分析
- 启动Screen时未加
-d -m参数,导致Screen以交互模式运行,依赖Python进程的stdin管道。当Python方法返回、进程退出时,stdin管道被关闭,Screen会认为输入结束,直接退出。 DETACHED_PROCESS是Windows平台的进程创建标志,而Screen是Linux/Unix专属工具,这个参数完全无效。- 通过
proc.stdin.write传递命令的方式不可靠:Screen的交互模式需要完整的终端环境,subprocess的管道无法模拟终端行为,很容易导致命令执行失败或会话退出。
正确的实现代码
推荐:不使用shell=True的安全版本
import subprocess def start_detached_screen(session_name, script_path, cwd=None): # 使用screen -d -m参数直接后台启动会话并执行指定脚本 # 用bash -c包裹脚本路径,支持带参数的脚本 proc = subprocess.Popen( ['screen', '-S', session_name, '-d', '-m', 'bash', '-c', script_path], cwd=cwd, # 重定向所有管道到/dev/null,避免父进程退出时影响Screen会话 stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL ) proc.wait() # 等待Screen启动完成 return proc.returncode
兼容原写法:使用shell=True的版本(不推荐)
如果坚持用shell=True,可以这样写:
import subprocess def start_detached_screen(session_name, script_path, cwd=None): cmd = f'screen -S {session_name} -d -m bash -c "{script_path}"' proc = subprocess.Popen( cmd, shell=True, cwd=cwd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, stdin=subprocess.DEVNULL ) proc.wait() return proc.returncode
关键说明
-d -m参数:这是Screen后台启动的标准方式,启动后会话会立即进入分离状态,独立于父进程运行,即使Python脚本或IPython会话退出,Screen会话也会继续保持。- 管道重定向:把stdout、stderr、stdin都重定向到
/dev/null,可以避免父进程的管道资源未释放导致的问题,同时也不会在Python端产生无用的输出。 - 脚本执行:用
bash -c包裹脚本路径,支持带命令行参数的脚本(比如script_path="python my_script.py --arg 123")。
使用示例
# 启动名为"my_session"的Screen会话,运行当前目录下的run_script.sh start_detached_screen("my_session", "./run_script.sh", cwd="./")
内容的提问来源于stack exchange,提问作者Alvin Gavel
相关产品推荐
相关产品推荐

