Linux使用经验(一)------离线运行python脚本
nohup 是 Linux/Unix 系统中用于忽略挂起信号(SIGHUP)的命令,结合 Python 执行代码时,能实现后台持续运行脚本(即使终端断开、
一、基础用法
1. 核心命令格式
bash
nohup python [Python参数] 脚本名.py [脚本参数] > 输出日志文件 2>&1 &
| 部分 | 说明 |
|---|---|
nohup |
核心命令,忽略挂起信号,保证程序后台运行 |
python |
Python 解释器(可替换为 python3/python3.9 等指定版本) |
[Python参数] |
Python 运行参数(如 -u 禁用缓冲、-O 优化执行、-m 运行模块等) |
脚本名.py |
要执行的 Python 脚本(绝对路径/相对路径) |
[脚本参数] |
传递给 Python 脚本的参数(脚本内可通过 sys.argv 获取) |
> 输出日志文件 |
重定向标准输出(stdout)到指定文件(默认生成 nohup.out) |
2>&1 |
将标准错误(stderr)重定向到标准输出(最终写入同一个日志文件) |
& |
将进程放入后台运行(终端可继续执行其他命令) |
2. 最简示例
执行 test.py,日志默认写入 nohup.out:
bash
nohup python3 test.py &
3. 自定义日志文件(推荐)
将日志写入 test.log,方便后续排查问题:
bash
nohup python3 -u test.py > test.log 2>&1 &
- 关键参数
-u:禁用 Python 输出缓冲,保证日志实时写入文件(否则日志可能延迟显示)。
4. 传递脚本参数
如果脚本需要接收参数(如 test.py 需传入 --mode prod --port 8080):
bash
nohup python3 -u test.py --mode prod --port 8080 > test.log 2>&1 &
脚本内可通过 sys.argv 或 argparse 解析参数。
二、关键操作
1. 查看后台运行的 Python 进程
bash
# 方法1:查看所有后台进程(含nohup启动的)
jobs -l
# 方法2:过滤Python进程(更精准)
ps -ef | grep python3 | grep test.py
# 方法3:仅显示进程ID(PID)
pgrep -f test.py
2. 终止后台运行的 Python 进程
找到进程 PID 后,用 kill 命令终止:
bash
# 正常终止(推荐,允许程序清理资源)
kill [PID]
# 强制终止(程序无响应时使用)
kill -9 [PID]
示例:
bash
# 先查PID
ps -ef | grep test.py # 假设输出 PID 为 12345
# 再终止
kill 12345
3. 查看实时日志
bash
# 实时跟踪日志输出(类似 tail -f)
tail -f test.log
# 查看最后100行日志
tail -n 100 test.log
# 查看全部日志
cat test.log
三、进阶技巧
1. 后台运行虚拟环境中的 Python
如果脚本依赖虚拟环境,需指定虚拟环境的 Python 解释器路径:
bash
# 假设虚拟环境在 ~/venv 下
nohup ~/venv/bin/python3 -u test.py > test.log 2>&1 &
2. 避免日志文件过大
结合 logrotate 分割日志,或直接限制日志大小(示例:日志超过 100MB 则覆盖):
bash
nohup python3 -u test.py > >(tail -c 100M) 2>&1 &
3. 开机自启(以 systemd 为例)
如果需要脚本开机自动运行,可创建 systemd 服务:
-
创建服务文件:
bashsudo vim /etc/systemd/system/test.service -
写入内容:
ini[Unit] Description=Python Test Script After=network.target [Service] Type=simple User=root # 替换为实际运行用户 ExecStart=/usr/bin/python3 -u /path/to/test.py # 替换为实际脚本路径 Restart=on-failure # 程序崩溃时自动重启 StandardOutput=append:/path/to/test.log # 日志输出 StandardError=append:/path/to/test.log [Install] WantedBy=multi-user.target -
启用并启动服务:
bashsudo systemctl daemon-reload sudo systemctl enable test.service sudo systemctl start test.service
四、常见问题
-
日志无输出:
- 忘记加
-u参数,Python 缓冲输出导致日志延迟,添加-u即可。 - 日志文件权限不足,检查文件所属用户和权限(
chmod 777 test.log临时测试)。
- 忘记加
-
进程莫名终止:
- 脚本本身抛出未捕获的异常,查看日志文件排查错误。
- 系统资源不足(内存/CPU 耗尽),通过
dmesg或top排查。 - 终端关闭时仍发送了 SIGHUP 信号,确认命令末尾加了
&。
-
中文日志乱码:
-
在脚本开头设置编码:
pythonimport sys sys.stdout.reconfigure(encoding='utf-8') sys.stderr.reconfigure(encoding='utf-8')
-
总结
核心命令:nohup python3 -u 脚本.py > 日志文件 2>&1 &
关键参数:-u(实时日志)、2>&1(合并错误输出)、&(后台运行)
运维技巧:结合 ps/kill 管理进程、tail -f 查看日志、systemd 实现开机自启。