目录一、引言那个被关闭终端杀死的程序二、前台与后台终端里的“舞台”与“后台”2.1 基本概念2.2 CtrlZ暂停并放入后台2.3 jobs查看后台作业2.4 bg让暂停的后台作业继续运行2.5 fg把后台作业调回前台2.6 直接后台启动2.7 完整操作流程演示三、kill不是“杀死”是“发信号”3.1 一个常见的误解3.2 最常用的两个信号15和93.3 其他常用信号3.4 killall和pkill按名称发信号四、终端关闭后如何保持程序运行4.1 nohup最简单的保活方案4.2 screen终端会话的“保存与恢复”4.3 tmuxscreen的现代化替代品五、综合实战一个完整的远程训练任务六、本篇小结动手练习七、下篇预告一、引言那个被关闭终端杀死的程序有没有遇到过这种场景你用SSH连上服务器启动了一个需要跑很久的脚本然后你关闭了笔记本盖子去吃饭。回来后重新连上服务器发现脚本没了——它在你断开SSH的那一刻就被系统杀掉了。这不是bug而是Linux的设计机制当终端关闭时系统会向该终端启动的所有进程发送SIGHUP信号默认行为是终止进程。理解这个机制并学会让程序在“后台”独立运行是运维和开发中的必修课。今天我们就来解决这个问题。二、前台与后台终端里的“舞台”与“后台”2.1 基本概念当你打开终端执行一条命令时默认是“前台运行”bashsleep 100执行后你的终端被这个命令“占据”了——光标闪烁但你输入任何东西都没反应。此时你有三个选择耐心等它执行完按CtrlC强制终止它把它“甩”到后台去前台进程和后台进程的核心区别对比维度前台进程后台进程占用终端是执行期间无法输入其他命令否终端可以继续使用接收键盘输入可以不能尝试读取会暂停被CtrlC终止会不会终端关闭时会被杀死也会被杀死除非用特殊手段2.2 CtrlZ暂停并放入后台CtrlZ的作用是暂停当前前台进程并将其放入后台作业队列。bashsleep 100 # 按 CtrlZ你会看到类似输出text[1] Stopped sleep 100此时sleep进程并没有死而是处于暂停状态等待你的下一步指令。2.3 jobs查看后台作业jobs命令列出当前终端会话中的所有后台作业bashjobs # 输出示例 # [1]- Stopped sleep 100 # [2] Running python train.py 每行开头的[1]是作业号这是你后续操作该作业的“句柄”。2.4 bg让暂停的后台作业继续运行bgbackground让一个已暂停的后台作业在后台继续运行bashbg %1 # 让作业号为1的作业在后台继续运行 bg # 不带参数默认操作最近一个作业带号的注意%1这个写法——在操作后台作业时需要用%加作业号来指定目标以区别于普通命令的参数。2.5 fg把后台作业调回前台fgforeground把后台作业拉回前台运行bashfg %1 # 把作业1调回前台 fg # 默认操作最近一个作业调回前台后这个作业会重新占据你的终端你可以与它正常交互也能用CtrlC终止它。2.6 直接后台启动如果你从一开始就知道某个命令要跑很久可以在命令末尾加让它直接后台启动bashsleep 100 # 输出[1] 12345 方括号内是作业号后面是PID这样启动的进程直接处于运行状态不需要再按CtrlZ然后bg。2.7 完整操作流程演示bash# 场景启动一个长时间任务中途想临时做点别的事 # 1. 前台启动任务 python train_model.py # 2. 按 CtrlZ 暂停并放入后台 # 看到 [1] Stopped # 3. 让它在后台继续跑 bg %1 # 4. 干点别的事比如查看日志 tail -f training.log # 5. 想看训练进度了把任务拉回前台 fg %1 # 6. 不需要了CtrlC 终止三、kill不是“杀死”是“发信号”3.1 一个常见的误解很多初学者以为kill就是“杀死进程”的命令。但实际上kill的真实作用是向进程发送信号。至于收到信号后进程做什么取决于信号的类型和进程自身的处理逻辑。bashkill -l # 列出所有支持的信号你会看到64个不同的信号从1到64各有不同的含义。“终止进程”只是其中一部分信号的功能。3.2 最常用的两个信号15和9信号编号信号名含义进程能否捕获/忽略15SIGTERM终止信号Terminate能9SIGKILL强制杀死Kill不能SIGTERM15——优雅退出这是kill命令的默认信号。当你执行kill PID时实际上发送的是SIGTERM。收到SIGTERM的进程可以执行清理工作保存数据、关闭文件、释放资源决定要不要退出甚至完全忽略这个信号大多数编写规范的程序在收到SIGTERM后会优雅退出——先完成手头的工作再自行结束。这就是为什么推荐先用kill PID试试不行再用kill -9。SIGKILL9——强制终止kill -9 PID发送的是SIGKILL信号。这个信号进程无法捕获、无法忽略、无法执行任何清理操作——内核直接终止进程。它是最“暴力”的手段应该作为最后的选择。因为进程没机会保存数据可能导致文件损坏进程持有的锁不会被释放可能导致其他进程卡住共享内存可能残留需要手动清理3.3 其他常用信号信号编号作用典型场景SIGHUP1挂断信号重新加载配置文件nginx -s reloadSIGINT2中断信号CtrlC就是发送这个信号SIGKILL9强制杀死进程卡死其他方式无效时的最后手段SIGTERM15终止信号正常的“请退出”请求SIGSTOP19暂停进程CtrlZ的底层实现SIGCONT18继续运行bg或fg唤醒暂停进程3.4 killall和pkill按名称发信号如果每次都先ps找PID再kill效率太低。killall和pkill允许你直接用进程名发信号bash# 优雅终止所有nginx进程 killall nginx # 强制杀死所有python进程 killall -9 python # pkill支持模糊匹配 pkill -f python train # 匹配包含python train的完整命令行警告killall会向所有匹配名称的进程发送信号务必确认没有误伤重要进程。四、终端关闭后如何保持程序运行回到开篇的问题SSH断开后怎么让程序继续跑解决方案有两种思路轻量级nohup适合临时跑一个长任务重量级screen或tmux适合需要持续交互的复杂场景4.1 nohup最简单的保活方案nohupno hang up的作用是让进程忽略SIGHUP信号。终端关闭时系统发送的正是这个信号。bashnohup 命令 标准用法bashnohup python train_model.py output.log 21 这条命令做了三件事nohup忽略SIGHUP终端关了也不影响 output.log 21把标准输出和错误输出都重定向到文件nohup默认会生成nohup.out这里指定自己的日志文件放到后台运行执行后会显示text[1] 12345现在你可以放心关闭终端或断开SSH进程会继续运行。回来后想看进度bashtail -f output.log想终止它bashkill 12345 # 用之前显示的PID4.2 screen终端会话的“保存与恢复”nohup的局限在于一旦放到后台你就无法再和程序交互了。如果训练脚本需要中途输入参数nohup无能为力。screen解决了这个问题——它创建一个独立的终端会话你可以随时“分离”detach和“重新接入”attach就像保存游戏进度一样。安装bashsudo apt install screen -y # Ubuntu/Debian sudo dnf install screen -y # CentOS/RHEL核心操作流程bash# 1. 创建一个命名会话 screen -S train # 2. 在新窗口中执行你的命令 python train_model.py # 3. 按 CtrlA 然后按 D —— 分离会话Detach # 你会回到原来的终端train会话在后台继续运行 # 4. 断开SSH吃饭睡觉回来重新连接 # 5. 重新接入之前的会话 screen -r train # 6. 你又看到了正在运行的训练脚本就像从未离开过常用命令速查命令作用screen -S 名称创建命名会话screen -ls查看所有会话screen -r 名称重新接入会话screen -d 名称强制分离会话如果卡住了screen -X -S 名称 quit彻底结束会话screen内部快捷键先按CtrlA再按下一个键快捷键作用CtrlAD分离会话最常用CtrlAK杀死当前窗口CtrlAC创建新窗口CtrlAN切换到下一个窗口CtrlA列出所有窗口4.3 tmuxscreen的现代化替代品tmux功能比screen更强大支持窗口分割、更灵活的配置。但对于“保活长任务”这个需求screen足够用。如果你以后需要更复杂的终端复用功能可以去了解tmux。五、综合实战一个完整的远程训练任务假设你要在服务器上训练一个深度学习模型预计要跑24小时。完整操作流程如下第一步创建screen会话bashssh userserver screen -S model_training第二步启动训练bashcd ~/project python train.py --epochs 100 21 | tee training.logtee让我们既能实时看输出又能保存到文件第三步分离会话text按 CtrlA 然后按 D看到[detached]提示回到普通终端。第四步断开SSH回家睡觉第五步第二天重新连接查看bashssh userserver screen -r model_training你又看到了训练进度就像从未离开过。第六步如果训练已完成结束会话在screen内输入exit或按CtrlAK。六、本篇小结今天掌握了进程控制的三个核心技能前后台切换CtrlZ暂停前台任务并放入后台bg让暂停的任务在后台继续运行fg把后台任务拉回前台jobs查看当前会话的后台作业信号控制kill的本质是“发送信号”不是“杀死”先用kill PIDSIGTERM程序可优雅退出实在不行再用kill -9 PIDSIGKILL进程保活nohup 命令 临时防断线不需要交互screen -S 会话名需要随时接入交互的复杂任务选择建议场景推荐方案跑一个脚本跑完就完事不需要看进度nohup ... 跑一个长任务想随时看进度/暂停/改参数screen一次性命令但想让它在后台跑不影响继续工作command 动手练习bash# 1. 练习前后台切换 sleep 200 jobs fg %1 # 按 CtrlZ 暂停 bg %1 kill %1 # 用作业号也能kill # 2. 体验信号区别 # 启动一个能捕获信号的进程如top top # 另一个终端执行 kill PID # top正常退出 kill -9 PID # 再次启动top这次用-9观察差异 # 3. 练习screen screen -S test # 在screen内执行top # 按 CtrlA D 分离 screen -ls # 查看会话列表 screen -r test # 重新接入 # 在screen内按 q 退出top然后 exit 退出screen # 4. 练习nohup nohup ping localhost ping.log 21 # 关闭终端重新打开 tail -f ping.log # 确认ping仍在运行 killall ping # 清理七、下篇预告掌握了进程的查看与控制下一篇我们将关注另一个系统核心资源——磁盘。《磁盘管理与文件系统》将带你了解df -h和du -sh如何排查磁盘空间问题lsblk查看磁盘和分区信息mount/umount挂载U盘和ISO镜像/etc/fstab实现开机自动挂载你会学会如何给Linux“加硬盘”以及当磁盘空间告急时如何快速定位是哪些文件在占地方。延伸思考试试执行kill -l数一数有多少个信号。其中有没有你完全看不懂名字的别担心即使是资深运维日常用到的也就五六个。关键是理解“信号是一种进程间通信方式”这个核心概念。