核心问题:为什么终端一关,脚本就停了?
想象一下,你通过远程桌面(SSH终端)登录到服务器,运行了一个脚本。这个脚本就像是你亲手打开的一个普通电脑程序。
当你断开远程桌面(退出SSH)时,就相当于把服务器的“显示器、键盘和鼠标”都拔掉了。操作系统会觉得:“哦,用户已经下班了,那他打开的这些程序也可以关掉了。” 于是它会发送一个“关闭”信号,把你运行的脚本给终止了。
我们的目标就是:让脚本摆脱这个“终端窗口”的束缚,把它变成一个在后台独立运行的“系统服务”或“守护进程”。
方法一:nohup
命令 - “拔掉电源线也能工作”
这是最简单、最快捷的方法,适合临时性的任务。
通俗理解:你告诉脚本:“嘿,即使我拔掉电源线(退出终端),你也要装作没听见,继续干你的活。” 同时,它会把脚本的所有输出(比如
print
语句)自动保存到一个文件里,以免丢失。使用方法:
nohup python your_script.py &
nohup
:是 no hang up 的缩写,意思就是“不挂断”。&
:这个符号表示“在后台运行”。运行后,它会告诉你一个 进程ID(PID),比如
[1] 12345
,这个12345
就是进程号,可以用来后续管理。脚本的所有输出默认会保存在当前目录下的
nohup.out
文件里。
如何查看和停止?
查看:
tail -f nohup.out
(实时查看输出日志)停止:先找到进程ID
ps aux | grep your_script.py
,然后kill 12345
优缺点:
优点:超级简单,无需配置。
缺点:脚本不是“服务”,服务器重启后不会自动拉起;不适合管理复杂的长期服务。
方法二:tmux
或 screen
- “虚拟会议室”
这两个工具功能类似,我们以更流行的 tmux
为例。
通俗理解:你在服务器上创建了一个永不停息的“虚拟会议室”。你在这个会议室里运行脚本,然后你可以随时“离开会议室”(断开连接),但会议室里的所有工作都会照常进行。等你下次回来,可以再“进入会议室”,看到一切如初。
使用方法:
安装tmux (如果服务器没有):
sudo apt-get install tmux
(Ubuntu/Debian)创建一个新会议室:
tmux new -s my_script_room
在会议室里正常运行脚本:
python your_script.py
“离开”会议室:按下
Ctrl + B
,松开后,再按D
键。现在你回到了服务器的普通终端,但脚本仍在my_script_room
会议室里运行。下次回来“进入”会议室:
tmux attach -t my_script_room
如何停止?
进入会议室后,直接按Ctrl + C
停止脚本,然后输入exit
关闭会议室。优缺点:
优点:非常灵活,可以实时看到脚本的输出和状态,就像它从来没停过一样;适合调试和交互式任务。
缺点:同样不是“服务”,服务器重启后会议室就没了;更依赖于用户的手动管理。
方法三:Systemd - “把它变成系统服务”(推荐用于生产环境)
这是最专业、最可靠的方法,用于管理需要一直运行的关键服务(比如Web服务器、数据库、你的核心业务脚本)。
通俗理解:就像你把一个程序图标拖到Windows的“启动”文件夹里,开机就能自动运行。Systemd是Linux系统的“大管家”,它负责启动、停止和管理所有系统服务。你把脚本交给它,它就把它当作一个系统级别的服务来管理:开机自启、崩溃重启、统一日志管理等。
使用方法:
创建一个服务配置文件(例如:
my_python_service.service
)sudo nano /etc/systemd/system/my_python_service.service
写入以下配置内容(根据你的情况修改):
[Unit] Description=My Python Script # 服务描述 After=network.target # 在网络服务启动后再启动本脚本[Service] Type=simple User=ubuntu # 用哪个用户身份运行,很重要! WorkingDirectory=/home/ubuntu/my_scripts # 脚本所在目录 ExecStart=/usr/bin/python3 /home/ubuntu/my_scripts/your_script.py # 启动命令 Restart=always # 崩溃时自动重启 RestartSec=5 # 重启前等待5秒[Install] WantedBy=multi-user.target # 表示在系统多用户模式下启用
让Systemd重新加载配置:
sudo systemctl daemon-reload
启动你的服务:
sudo systemctl start my_python_service
设置开机自启:
sudo systemctl enable my_python_service
如何管理?(一套万能命令)
启动:
sudo systemctl start my_python_service
停止:
sudo systemctl stop my_python_service
重启:
sudo systemctl restart my_python_service
查看状态:
sudo systemctl status my_python_service
(这个最常用!)查看实时日志:
sudo journalctl -u my_python_service -f
优缺点:
优点:极其强大和稳定;自动重启;开机自启;有完善的生命周期管理;日志统一收集。
缺点:需要 root 权限来配置;配置稍复杂。
方法四:Supervisor - “专职进程保姆”
这是一个专门用来管理进程的工具,介于 tmux
的灵活和 Systemd
的强大之间。
通俗理解:你雇了一个“专职保姆”。你把脚本交给它,并下达指令:“这个孩子(脚本)你给我看好了,如果他摔倒了(崩溃了),马上把他扶起来(重启)。” Supervisor 会 7x24 小时盯着你的进程。
使用方法:
安装:
sudo apt-get install supervisor
创建配置文件(例如:
my_script.conf
)在/etc/supervisor/conf.d/
目录下。写入配置:
[program:my_python_script] ; 你的服务名 command=python3 /path/to/your_script.py ; 启动命令 directory=/path/to/your_script ; 工作目录 user=ubuntu ; 运行用户 autostart=true ; 是否自启 autorestart=true ; 是否自动重启 stderr_logfile=/var/log/my_script.err.log ; 错误日志 stdout_logfile=/var/log/my_script.out.log ; 输出日志
让Supervisor重新加载并运行:
sudo supervisorctl reread sudo supervisorctl update sudo supervisorctl start my_python_script
如何管理?
sudo supervisorctl status
:查看所有管理的进程状态。sudo supervisorctl stop my_python_script
:停止。sudo supervisorctl restart my_python_script
:重启。
优缺点:
优点:配置比 Systemd 更直观,专门为管理进程而生;监控功能强大;不需要 root 权限也能管理部分功能(通过配置)。
缺点:需要额外安装一个软件。
总结与选择建议
方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
nohup | 临时测试,运行一个几个小时的数据处理脚本。 | 最简单,零配置 | 不稳定,不易管理 |
tmux/screen | 开发/调试,需要实时观察输出的长任务。 | 灵活,可交互 | 非服务化,依赖会话 |
Systemd | 生产环境,公司网站、API服务、核心后台任务。 | 强大稳定,专业 | 配置需root权限 |
Supervisor | 生产环境(特别是非root用户),或需要精细控制进程。 | 功能专一,配置直观 | 需额外安装 |
给你的最终建议:
如果你是临时跑个脚本,用
nohup
或tmux
。如果你做开发,需要看实时日志,用
tmux
。如果你的脚本是公司的重要服务,需要永远运行,毫不犹豫地选择
Systemd
。这是现代Linux服务器的标准和最佳实践。