第56课 - nohup、screen 与 tmux:让你的进程“永生”
所属模块: 进程管理 难度: Intermediate 标签: nohup, tmux, screen 上一课: 后台前台与作业控制 下一课: systemd 体系入门
1. 学习目标
完成本课学习后,你将能够:
- 理解与使用
nohup: 能够使用nohup使进程在用户退出登录后继续运行。 - 掌握终端复用器的核心思想: 理解
screen和tmux作为“虚拟终端管理器”的作用,并学会基本操作。 - 区分与选用工具: 能够根据场景(简单后台任务 vs. 交互式会话管理)在
nohup、screen和tmux之间做出合理选择。 - 实践会话管理: 能够创建、分离、附加和管理
tmux会话,保障重要工作的连续性。
2. 核心概念
2.1 nohup:最简单的“免打扰”模式
想象一下,你正在通过SSH连接到服务器运行一个长时间的数据处理脚本。如果直接运行,一旦网络断开或终端关闭,你的进程也会随之终止。nohup 的作用就是告诉Linux内核:“忽略(Ignore)发送给这个进程的‘挂断’(HUP)信号”。这样,即使你退出登录,进程也不会收到“主人要走了,你也该结束”的信号,从而继续在后台默默运行。
核心语法:
nohup 命令 [参数] &
& 表示将命令放到后台执行。nohup 会自动将命令的标准输出重定向到当前目录的 nohup.out 文件中(如果没有权限,则会重定向到 $HOME/nohup.out)。
2.2 screen:传统的“虚拟多面手”
screen 可以看作是一个虚拟终端窗口管理器。你可以把它想象成一个拥有多个“虚拟显示器”的工位。
- 创建会话: 就像在工位上开启一台新的显示器。
- 分离(Detach): 临时离开你的物理工位(退出SSH),但所有虚拟显示器上的工作都保持原样。
- 附加(Attach): 回到工位后,重新接管之前的虚拟显示器,继续工作。
2.3 tmux:现代的“虚拟工位管家”
tmux (Terminal Multiplexer) 是 screen 的现代替代品,功能更强大,配置更灵活。它引入了三层结构:
- 服务器:
tmux以一个后台服务进程运行。 - 会话(Session): 代表一个完整的任务集合,如“开发环境”、“运维监控”。即使断开,会话依然存在。
- 窗口(Window): 会话中的一个全屏终端窗口,可以理解为浏览器的一个标签页。
- 面板(Pane): 窗口内可以分割出的多个小区域,让你同时查看或操作多个任务(例如:上半屏写代码,下半屏看日志)。这是
tmux相较于screen的一大优势。
3. 代码示例
3.1 使用 nohup 运行后台脚本
# 1. 创建一个简单的Python脚本,它会每3秒打印一次时间
cat > long_running_task.py << 'EOF'
import time
import datetime
print("任务开始...")
while True:
print(f"当前时间: {datetime.datetime.now()}")
time.sleep(3)
EOF
# 2. 使用nohup在后台运行它,并将输出重定向到my_task.log
nohup python3 long_running_task.py > my_task.log 2>&1 &
# 输出示例:
# [1] 12345 # 这是该后台作业的进程ID(PID)
# 3. 你可以用jobs命令查看当前shell的后台作业,或用ps命令查看所有进程
jobs
ps aux | grep long_running_task
# 4. 现在,即使你关闭当前终端,重新登录后,进程仍在运行。用tail命令查看日志:
tail -f my_task.log
3.2 tmux 基础操作:创建、分离与附加
# 1. 创建一个新的tmux会话,命名为‘dev_work’
tmux new -s dev_work
# 现在你进入了一个tmux会话,感觉和普通终端一样,但左下角有状态栏。
# 2. 在tmux会话内,你可以正常运行任何命令,比如启动一个长时间脚本:
python3 long_running_task.py
# 3. 按下快捷键 `Ctrl+b` 然后按 `d`,你会看到“[detached (from session dev_work)]”。
# 这表示你成功从会话“分离”了出来,回到了之前的普通shell。
# 但你的Python脚本依然在tmux会话里运行着!
# 4. 查看当前所有tmux会话:
tmux ls
# 输出示例:
# dev_work: 1 windows (created Mon Jul 10 14:30:00 2023)
# 5. 重新附加(Attach)到之前的会话:
tmux attach -t dev_work
# 你会瞬间回到之前离开时的状态,脚本还在输出。
# 6. 会话使用完毕,可以在会话内输入 `exit` 或按 `Ctrl+d` 来关闭它。
3.3 tmux 进阶:创建分割面板
# 1. 创建或附加到一个tmux会话
tmux new -s admin_panel
# 2. 水平分割面板:按 `Ctrl+b` 然后按 `%` (Shift+5)
# 现在你有了左右两个面板
# 3. 垂直分割面板:按 `Ctrl+b` 然后按 `"` (Shift+’)
# 你可以在当前面板(比如左侧)上再分割出上下两个面板
# 4. 在不同面板间切换:按 `Ctrl+b` 然后按方向键 `←` `→` `↑` `↓`
# 5. 在左侧上面板运行 `top` 命令监控系统资源。
# 6. 切换到右侧面板,运行 `tail -f /var/log/syslog` 查看系统日志。
# 7. 现在你只需一个窗口,就能同时监控两件事。
4. 实践练习
练习1:基础后台任务
要求:编写一个Bash脚本,使用 sleep 模拟一个需要运行60秒的任务。使用 nohup 将其放入后台运行,并将输出重定向到 ~/practice/nohup_test.log。退出登录后重新连接,验证进程是否仍在运行。
练习2:tmux分屏监控 要求:
- 创建一个名为
monitor的tmux会话。 - 在该会话中,将窗口垂直分割为左右两个面板。
- 在左侧面板运行
htop(如果没有,用top)。 - 在右侧面板运行
watch -n 2 df -h(每2秒刷新磁盘空间)。 - 分离会话,过1分钟后重新附加,确认两个面板的任务都还在运行。
练习3:选择合适的工具
场景:你需要在一台远程服务器上编译一个大型项目(如Linux内核),这需要数小时。你必须断开SSH连接。你会选择使用 nohup、screen 还是 tmux?请说明你的选择理由。
5. 常见错误
-
忘记
&和输出重定向: 使用nohup时忘记加&,导致命令并未真正放入后台,你无法输入新命令。忘记重定向输出,导致屏幕被信息刷屏,且退出后无法查看输出。- 错误命令:
nohup long_task.sh - 正确命令:
nohup long_task.sh > output.log 2>&1 &
- 错误命令:
-
直接关闭终端而非分离会话: 在使用
screen或tmux时,直接关闭终端窗口(而不是使用Ctrl+b d),这等同于杀死了整个会话及其内的所有进程。- 正确做法: 始终使用快捷键分离会话。
-
找不到之前的tmux会话: 使用
tmux a或tmux attach时报错 “no sessions”。可能是因为之前的会话已经退出,或者你使用了不同的用户运行tmux服务器。- 排查命令:
tmux ls查看现有会话。tmux new -s mysession重新创建。
- 排查命令:
-
权限问题:
nohup.out或自定义日志文件可能因为权限问题写入失败。确保你对目标目录有写权限。
6. 小结
nohup是运行单个、不需要交互的后台任务的简单有效方案。它通过忽略HUP信号使进程“不跟随”终端退出。screen和tmux是终端会话管理器,适用于需要多次、交互式地接入和断开的场景。它们能保存完整的终端状态。tmux是screen的现代化替代品,其“会话-窗口-面板”的三层结构更清晰,分屏功能更强大,社区支持更活跃,是当前的主流推荐。- 选择指南:
- 一次性、无需交互的命令 →
nohup command & - 需要保护交互式会话不被网络中断影响 →
tmux(或screen) - 需要同时在一个屏幕上监控多个任务 →
tmux的面板功能
- 一次性、无需交互的命令 →
记住: 对于重要的、长时间运行的任务,无论它是否交互,使用 tmux 或 screen 包裹起来,是一个值得培养的专业习惯。它能极大地提升你远程工作的可靠性和效率。