目录
一、引言
在日常的 Linux 运维或者后台管理中,我们经常需要在服务器上执行一些长时间运行的程序或脚本。问题在于,当我们通过 SSH 连接到服务器并启动程序后,如果网络断开或者我们主动关闭了终端窗口,程序往往也会被迫退出。这就需要一种能够让程序在后台保持运行的手段,从而保证任务的可靠性。
下面将从几个常见的方法入手,一一介绍它们的实现原理和具体使用方法。
二、使用 Screen
2.1 什么是 Screen
- Screen 是一个终端复用器(terminal multiplexer),可以在一个 SSH 会话中创建多个“虚拟终端会话”,并且即使你断开 SSH 连接,这些虚拟终端会话也能继续保持活动状态。
- 简单地理解,
screen
就像一个“屏幕管理器”。你可以开启一个“屏幕”,在这个“屏幕”里运行你的程序,即使 SSH 断开,这个“屏幕”也仍然存在。重新 SSH 登录后,可以重新连接到这个“屏幕”,继续之前的操作。
2.2 安装 Screen
大部分的 Linux 发行版(如 Ubuntu、CentOS、Debian 等)默认会自带 screen
工具。若未安装,可使用包管理器安装:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install screen
# CentOS
sudo yum install screen
# 或者使用 dnf
sudo dnf install screen
2.3 Screen 的常用命令
-
启动一个新的 screen 会话:
screen -S <会话名称>
其中
-S
参数指定会话名称,以便之后区分和管理。如果不加-S
,会话名称将会随机分配。 -
在 screen 中运行程序:
启动 screen 会话后,直接在此终端执行任何程序或脚本。例如:python my_script.py
-
从当前 screen 会话分离(detach):
在不结束会话的前提下返回常规终端,只需按快捷键Ctrl + A + D
。 -
查看现有的 screen 会话:
screen -ls
-
重新连接到一个已有的 screen 会话:
screen -r <会话名称或ID>
如果仅有一个会话在运行,则可直接
screen -r
。
2.4 退出/终止 Screen 会话
-
在会话内部手动退出:
- 在 screen 会话中输入
exit
,或按Ctrl + D
,即可终止当前 screen 会话。 - 若此会话中运行的程序已退出,screen 也会自动退出。
- 在 screen 会话中输入
-
强制终止某个会话(在外部):
- 如果想在不进入会话的情况下终止它,可执行:
或:screen -X -S <会话名称或ID> quit
screen -X -S <会话名称或ID> kill
- 如果想在不进入会话的情况下终止它,可执行:
2.5 常见用法示例
- 创建并执行程序:
screen -S my_session # 进入 screen 后执行长时间任务 python my_long_time_task.py # 按 Ctrl + A + D 放入后台
- 查看会话并重新连接:
screen -ls # 假设会话名/ID 为 1234.my_session screen -r 1234
- 终止会话:
- 在会话内部输入
exit
或Ctrl + D
; - 在外部:
screen -X -S 1234 kill
。
- 在会话内部输入
三、使用 tmux
3.1 什么是 tmux
- tmux(terminal multiplexer)同样是一个终端复用器,与
screen
功能相似。 - 它的配置和功能更为灵活、现代,可以实现多窗口、多面板拆分等特性。
3.2 安装 tmux
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install tmux
# CentOS
sudo yum install tmux
# 或使用 dnf
sudo dnf install tmux
3.3 tmux 的常用命令
- 启动新的 tmux 会话:
tmux new -s <会话名称>
- 分离会话:
默认快捷键Ctrl + b + d
。 - 查看现有会话:
tmux ls
- 重新连接到会话:
tmux attach -t <会话名称或ID>
- 退出/关闭会话:
在 tmux 会话中直接exit
或Ctrl + d
。
3.4 tmux 的窗口与面板
tmux 提供更多窗口与面板管理的功能:
- 新建一个窗口:
Ctrl + b + c
- 左右分屏:
Ctrl + b + %
- 上下分屏:
Ctrl + b + "
在同一 SSH 会话中管理多个终端、日志或监控非常方便。
四、使用 nohup
4.1 什么是 nohup
nohup
(no hang up)命令可让命令在登出(logout)或终端关闭后继续运行。- 若你的应用无需交互,仅需放在后台执行完毕即可,
nohup
是最直接的选择。
4.2 使用方法
在命令前加上 nohup
并在末尾加 &
,例如:
nohup python my_script.py > my_script.log 2>&1 &
> my_script.log 2>&1
:将标准输出和标准错误都重定向到my_script.log
文件。&
:表示在后台运行。
即使关闭终端,该程序也会继续在后台运行。通过 ps -ef | grep my_script.py
查看进程是否在运行,或查看日志文件内容。
4.3 注意事项
- 若不显式指定输出文件,默认会将输出重定向到
nohup.out
。 - 无法交互,需要借助日志或进程管理命令来查看状态。
五、使用作业控制(jobs + disown)
5.1 后台运行程序
在大多数 shell 中,在命令末尾加 &
即可后台运行,如:
python my_script.py &
系统会输出作业编号和进程 PID,例如:
[1] 12345
5.2 Ctrl + Z
+ bg
如果已经在前台执行程序,可以按 Ctrl + Z
将其暂停,然后执行:
bg
让它在后台继续运行。
5.3 断开 SSH 前使用 disown
将程序放到后台后,如果不加处理,当退出 shell 会话时系统会发送 SIGHUP 信号,进程会被终止。可以通过 disown
脱离与该进程的联系:
- 用
jobs
查看当前后台作业; - 对目标作业执行:
例如disown %<作业号>
disown %1
。
这样该作业与当前 shell 脱离,终端关闭后程序依旧继续运行。
5.4 总结
- 适合临时需求:若前台已启动的程序临时需要在后台继续执行又不想重启程序,可用
Ctrl + Z + bg + disown
“解救”它。 - 无法交互:不能像
screen/tmux
那样回连查看或操作,需要通过日志或进程管理来追踪。
六、使用守护进程/服务管理工具
若你的程序需要长期在后台运行,并具备自动启动、重启等需求,可使用更专业的服务管理工具:
- Systemd (systemctl)
- 大多数现代 Linux 发行版都使用 systemd。你可以编写一个
.service
文件托管应用:systemctl enable <service>
设置开机自启systemctl start/stop/restart <service>
控制服务状态
- 大多数现代 Linux 发行版都使用 systemd。你可以编写一个
- Supervisor
- 通用的进程管理工具,可监控进程、自动重启、记录日志等。
- Runit, OpenRC, Upstart 等
- 其他发行版采用的进程管理框架,可用于生产环境稳定运行、自动重启、集中化日志等。
七、总结
-
screen & tmux
- 可交互回连,在 SSH 断开后程序继续运行;
- 可多窗口、多面板,适合需要长期查看或多任务并行管理的场景。
-
nohup & disown
- 简单好用,无交互需求时就足够。
- 程序直接后台运行,需借助日志或进程管理命令查看。
-
服务管理工具
- 面向生产环境,可守护进程、自动重启、系统级管理;
- 需要一定的配置成本,但稳定性和可维护性更高。
根据你的需求和使用场景,选用最合适的方式即可。如果你经常需要查看输出日志、进行交互式调试或重新进入程序执行环境,那么 screen
或 tmux
会是不二之选。而若只是将脚本放到后台简单执行并不需要交互,则 nohup
/disown
就足以。若要让程序做成真正的服务且具备自动化管理和监控,使用 Systemd 或 Supervisor 等守护进程工具才是更佳方案
参考:
0voice · GitHub