SSH断开后保持Python程序运行的完整解决方案

10 次阅读

SSH断开后保持Python程序继续运行,是Linux服务器开发、远程部署和后台任务执行中经常遇到的问题。很多开发者会通过SSH连接云服务器运行Python脚本,例如数据采集、模型训练、定时任务、Web服务启动等,但当关闭终端窗口、网络异常中断或SSH连接超时时,Python程序往往也会随之停止。

出现这种情况的根本原因是:SSH会话结束后,系统通常会向该会话启动的前台进程发送终止信号(SIGHUP),程序收到信号后退出。因此,如果希望Python程序长期运行,需要将任务从当前SSH会话中脱离,或者使用专业的进程管理工具。

下面介绍几种常见且可靠的方法,并分析它们的适用场景。

方法一:使用nohup后台运行Python程序

nohup是Linux系统中最简单的后台运行工具,可以让程序忽略SSH断开时发送的挂起信号。

执行命令:

Bash
nohup python3 app.py &

其中:

  • nohup表示忽略SIGHUP信号;

  • python3 app.py表示运行Python程序;

  • &表示让程序进入后台执行。

运行后通常会看到:

Bash
nohup: ignoring input and appending output to 'nohup.out'

程序输出会自动保存到当前目录下的:

Bash
nohup.out

文件中。

查看程序是否运行:

Bash
ps -ef | grep python

或者:

Bash
pgrep -af python

停止程序:

Bash
kill 进程ID

如果程序无法退出,可以使用:

Bash
kill -9 进程ID

指定日志文件

实际项目中通常不建议直接使用默认日志文件,可以手动指定:

Bash
nohup python3 app.py > app.log 2>&1 &

含义:

  • > 将标准输出写入app.log;

  • 2>&1 将错误输出也写入同一个文件;

  • & 后台运行。

这种方式适合简单脚本,例如:

  • 数据处理任务;

  • 爬虫程序;

  • 自动化脚本;

  • 一次性运行的计算任务。

但如果是长期运行的服务,推荐使用后面的方案。


方法二:使用screen保持SSH断开后运行

screen是一种虚拟终端工具,可以创建一个独立于SSH连接之外的会话。

安装:

Ubuntu/Debian:

Bash
sudo apt install screen

CentOS:

Bash
sudo yum install screen

创建新的screen窗口:

Bash
screen -S python_task

进入后运行Python程序:

Bash
python3 app.py

此时即使关闭SSH连接,程序仍然会继续运行。

退出screen但不关闭程序:

按:

Ctrl + A

然后按:

D

即可退出当前screen会话。

重新连接:

Bash
screen -r python_task

查看所有screen:

Bash
screen -ls

结束screen:

Bash
screen -X -S python_task quit

screen相比nohup最大的优势是可以随时重新连接查看程序运行状态,非常适合需要人工观察输出的任务。


方法三:使用tmux管理后台Python任务

tmux是目前更流行的终端复用工具,功能类似screen,但操作更加灵活。

安装:

Ubuntu:

Bash
sudo apt install tmux

启动:

Bash
tmux new -s python_task

运行程序:

Bash
python3 app.py

退出当前窗口:

按:

Ctrl + B

然后:

D

重新进入:

Bash
tmux attach -t python_task

查看会话:

Bash
tmux ls

关闭会话:

Bash
tmux kill-session -t python_task

tmux适用于:

  • 长时间运行程序;

  • 服务器开发环境;

  • 机器学习训练任务;

  • 需要多窗口管理的场景。

相比screen,tmux配置能力更强,也是很多开发者管理远程服务器任务的首选工具。


方法四:使用systemd创建Python后台服务

如果Python程序需要长期运行,例如:

  • Flask接口服务;

  • FastAPI应用;

  • 自动任务程序;

  • 数据同步服务;

推荐使用Linux系统自带的systemd服务管理。

创建服务文件:

Bash
sudo vim /etc/systemd/system/my_python.service

写入:

INI
[Unit]
Description=Python Application
After=network.target

[Service]
User=root
WorkingDirectory=/opt/python_app
ExecStart=/usr/bin/python3 /opt/python_app/app.py
Restart=always

[Install]
WantedBy=multi-user.target

参数说明:

WorkingDirectory

表示程序运行目录。

ExecStart

指定Python解释器和脚本路径。

Restart=always

表示程序异常退出后自动重启。

保存后重新加载:

Bash
sudo systemctl daemon-reload

启动服务:

Bash
sudo systemctl start my_python

设置开机启动:

Bash
sudo systemctl enable my_python

查看状态:

Bash
sudo systemctl status my_python

查看日志:

Bash
journalctl -u my_python -f

systemd相比nohup和screen更加适合生产环境,因为它具备:

  • 自动重启;

  • 开机启动;

  • 日志管理;

  • 状态监控;

  • 权限控制。


方法五:使用Python进程管理工具Supervisor

Supervisor是一款常用的进程守护工具,可以管理多个后台程序。

安装:

Bash
sudo apt install supervisor

创建配置:

Bash
sudo vim /etc/supervisor/conf.d/python_app.conf

示例:

INI
[program:python_app]
command=python3 /opt/app/app.py
directory=/opt/app
autostart=true
autorestart=true
stderr_logfile=/var/log/python_app.err.log
stdout_logfile=/var/log/python_app.out.log

重新加载配置:

Bash
sudo supervisorctl reread
sudo supervisorctl update

启动:

Bash
sudo supervisorctl start python_app

查看状态:

Bash
sudo supervisorctl status

Supervisor特别适合同时运行多个Python服务,例如:

  • 多个爬虫任务;

  • 多个后台脚本;

  • 微服务程序。


SSH断开后Python停止的常见原因

1. 忘记添加后台运行符号

错误:

Bash
python3 app.py

SSH关闭后程序会退出。

解决:

Bash
nohup python3 app.py &

2. 使用后台运行但没有忽略SIGHUP

错误:

Bash
python3 app.py &

虽然程序进入后台,但SSH关闭时仍可能收到终止信号。

解决:

Bash
nohup python3 app.py &

3. 程序依赖当前终端输入

部分Python程序会等待输入:

Python
运行
input("请输入:")

SSH断开后可能异常退出。

后台任务应避免依赖交互输入。


4. 日志文件持续增长

长期运行Python程序时,如果不断输出日志:

Python
运行
print("running")

可能导致日志文件无限增大。

建议:

  • 使用logging模块;

  • 配置日志轮转;

  • 定期清理历史日志。

例如:

Python
运行
import logging

logging.basicConfig(
    filename="app.log",
    level=logging.INFO
)

logging.info("程序启动")

不同场景下的推荐方案

使用场景推荐方式
临时执行脚本nohup
需要随时查看运行状态tmux/screen
长期运行服务systemd
多个Python进程管理Supervisor
深度学习训练任务tmux + 日志管理
生产环境接口服务systemd + 日志系统

如何选择最佳方案

如果只是运行几个小时的数据处理脚本,nohup已经足够:

Bash
nohup python3 task.py > task.log 2>&1 &

如果需要经常查看运行过程,可以选择:

Bash
tmux new -s task

如果程序需要全年稳定运行,例如服务器接口或后台服务,应采用:

Bash
systemd

通过服务管理方式运行,可以避免服务器重启、程序异常退出导致业务中断。


总结

SSH断开后保持Python程序运行,本质上是让程序脱离SSH会话管理。简单任务可以使用nohup实现后台运行,交互式任务适合使用screen或tmux,而生产环境中的Python服务更推荐使用systemd或Supervisor进行专业化管理。

根据程序的重要程度选择合适方案,可以有效避免SSH断开导致任务中断,提高Python程序在Linux服务器上的稳定性和可靠性。