Linux服务器后台持续运行Python脚本的方法
在Linux服务器上运行Python程序时,如果直接在远程SSH终端输入 python app.py,一旦终端关闭或网络意外中断,正在运行的脚本就会随会话一同被系统终止。要让Python脚本在断开SSH连接后依然持续稳定运行,核心逻辑是切断进程与当前控制终端的挂钩,或者借助进程守护程序进行生命周期管理。本文将详细讲解nohup、tmux终端复用器以及systemd系统服务守护这三种主流实用方案的实现步骤、适用场景与管理细节。
方法一:轻量快捷的 nohup 与 & 组合
nohup(no hang up)的作用是让进程忽略挂断信号(SIGHUP),配合末尾的 & 符号,可以让命令立即转入后台执行。这种方式无需安装额外工具,是所有Linux发行版自带的经典方案。
1. 标准执行命令
nohup python -u /path/to/script.py > /path/to/output.log 2>&1 &
这条命令包含几个关键参数,含义如下:
python -u:-u表示禁用标准输出与标准错误的缓冲。若不加该参数,Python默认会对输出进行行缓冲或块缓冲,导致日志文件不能实时刷新内容。> /path/to/output.log:将标准输出(stdout)重定向写入指定的日志文件中。2>&1:将标准错误(stderr,文件描述符2)合并重定向到标准输出(stdout,文件描述符1),确保脚本抛出的异常堆栈也能被完整记录到日志。&:通知Shell将该进程置于后台执行,终端会立即交还交互提示符。
2. 查看与终止进程
通过以下命令可以实时追踪日志输出,或者找到该进程的PID并进行关闭:
# 查看实时输出
tail -f /path/to/output.log
# 查找正在运行的脚本进程
ps aux | grep script.py
# 示例输出:
# user 12345 0.2 1.5 58492 32100 pts/0 S 10:00 0:05 python -u /path/to/script.py
# 终止进程
kill 12345
# 若进程无响应,可使用强杀信号(谨慎使用)
kill -9 12345
方法二:使用终端复用器(tmux / screen)
对于需要频繁查看控制台输出、临时介入交互或进行调试的脚本,终端复用工具(如 tmux 或 screen)是更加高效舒适的选择。它在服务端维持虚拟终端会话,即便SSH断开,该会话仍旧独立保活在服务器中,重新连上后可直接“附着”(Attach)回会话查看原样现场。
1. tmux 操作四步法
- 创建并进入会话:
执行后会进入一个新的终端界面,底部通常有一条绿色状态栏。tmux new -s my_py_job - 在前台正常启动脚本:
在此处能直接看到程序打印的所有实时输出。python script.py - 剥离会话(切出后台):
按快捷键
Ctrl + b,松开后再按键盘d(代表 Detach)。此时会退出tmux虚拟屏幕回到原来的Shell,Python程序在后台继续不间断运行。 - 重新接入会话(重新连入):
无论之后何时重新通过SSH登录服务器,只需输入:
即可立刻回到先前的屏幕,查看输出并进行交互。tmux attach -t my_py_job
方法三:生产级进程管理(systemd 系统服务)
如果Python脚本是需要长期稳定运行的核心服务(如Web API服务、消息队列消费者、定时同步服务),nohup和tmux都存在一个致命缺陷:服务器重启后不会自动拉起,且程序意外报错崩溃退出时无法自动重启。针对这种生产环境,应当使用现代Linux标准的系统服务管理器 systemd。
1. 编写 Unit 配置文件
在系统服务配置目录 /etc/systemd/system/ 下创建一个 .service 文件,例如 my_service.service:
[Unit]
Description=Python Background Worker Service
After=network.target
[Service]
Type=simple
User=www-data
WorkingDirectory=/var/www/myapp
ExecStart=/var/www/myapp/venv/bin/python -u app.py
Restart=always
RestartSec=5
StandardOutput=append:/var/log/my_service.log
StandardError=append:/var/log/my_service_error.log
[Install]
WantedBy=multi-user.target
关键参数配置说明:
User:指定运行脚本的系统用户,避免直接使用 root 运行非特权服务,提升安全性。WorkingDirectory:脚本运行的根目录,确保脚本中的相对路径正确解析。ExecStart:必须使用绝对路径!如果有虚拟环境,指定虚拟环境下的 Python 解释器路径。Restart=always:异常退出或崩溃时,systemd 会自动拉起重启。RestartSec=5:崩溃后等待 5 秒再执行重启,防止死循环快速刷爆资源。
2. 启动与开机自启命令
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启动服务
sudo systemctl start my_service
# 设置开机自动启动
sudo systemctl enable my_service
# 查看服务当前状态
sudo systemctl status my_service
# 查看服务产生的日志
sudo journalctl -u my_service -f
方案对比与选型决策指南
面对不同的业务需要,盲目选择过重或过轻的方案都会增加维护成本。下表汇总了三种方案的核心特性对比:
| 对比维度 | nohup + & | tmux / screen | systemd 服务 |
|---|---|---|---|
| 配置复杂度 | 极低(单行命令) | 低(需简单快捷键记忆) | 中等(需root权限及编写配置) |
| 崩溃自动拉起 | 不支持(挂了即停止) | 不支持(会话保留,程序终止) | 支持(可配置自动重启) |
| 服务器重启自启 | 不支持 | 不支持 | 支持(开机随系统就绪自启) |
| 交互恢复能力 | 无交互,只能读日志 | 强(完全恢复原控制台屏幕) | 通过 journalctl/统一日志查看 |
| 最佳适用场景 | 临时训练、数据导出、轻量脚本 | 长时间跑批、需人工巡检、调试 | 核心后端、生产API、长期稳定守护 |
总结与避坑建议
在实际部署与后台运维过程中,还需注意以下三项容易被忽视的细节:
- 注意输出缓冲机制: 在使用
nohup或systemd时,请务必给 Python 命令加上-u开关,或设置环境变量PYTHONUNBUFFERED=1,以避免因缓冲区未满导致无法在日志文件中及时观察到打印内容。 - 避免相对路径隐患: 后台脱机运行或被守护进程拉起时,当前工作目录通常会变为调用位置或根目录。脚本读取文件、加载模块时务必使用绝对路径,或使用
os.path.dirname(os.path.abspath(__file__))进行基准定位。 - 建立统一的日志轮转机制: 长期持续运行的脚本如果直接追加写入单个日志文件,数月后日志可能膨胀到数十GB占满磁盘空间。建议配合系统的
logrotate或 Python 内置的RotatingFileHandler做好日志按天切分与历史清理。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













