我用测试数据预估了一下,由于对方网站有极其严格的反爬限速限制,这个脚本在我的终端里,至少得连续跑 5 个小时才能彻底跑完。
“管他呢,今晚就让它在这台公司的跳板机上挂着跑吧!”我心满意足地在终端里敲下了启动命令,看着屏幕上一行行跳出的绿色抓取日志。 然后,我随手合上了我的 MacBook 盖子,背着包愉快地打卡下班了。
第二天一早,我兴冲冲地打开电脑,连上那台服务器,想去查看昨晚的大丰收。 结果我瞬间惊呆了:终端上显示着极其刺眼的 Connection closed by foreign host,而我查了一下抓取下来的数据,进度竟然仅仅停留在昨天我合上盖子的那一秒!
我瞬间崩溃了。这怎么可能?脚本明明是在远端那台 24 小时开机的服务器上跑的,为什么我仅仅是合上了我自己电脑的盖子断开了 SSH 连接,远端的脚本就会突然暴毙?
我把这个新手必踩的“惊天血坑”发给了 AI。 AI 告诉我一个极其残酷的操作系统底层真相:在 Linux 的世界里,你当前启动的所有程序,在底层都默认是依附于你当前这个 SSH 终端会话(Session)而活的。一旦你的网络断开或者窗口关闭,系统就会认为你人已经走了,于是它会无情地给该会话下的所有子程序发送一个挂断信号(SIGHUP),把你刚才跑的心血全部强杀!
“难道总不能让我一直开着电脑、并且保证一晚上网络连一秒钟都不能闪断吧?”我绝望地问。
AI 递给了我一张服务器世界的最高级别“免死金牌”:nohup。
挂断免疫护身符:nohup
nohup 的全称极其直白:No Hang Up(不要挂断)。它的作用就是强行切断你的程序和当前终端会话之间的“连坐”关系。 当加上它之后,即使你的终端窗口关闭,系统发送了死亡的 SIGHUP 信号,这个程序也会极其傲娇地免疫这个信号,继续存活。
但如果只用 nohup,还有一个极其恶心的问题:它虽然不死,但它依然会死死地霸占着你当前的终端屏幕,疯狂往外喷吐日志,让你没法敲别的命令干别的工作。
所以,nohup 必须要配合另一个极其经典的符号 & 一起使用。&(Ampersand)的作用是:把这个程序直接扔进系统的后台暗处去跑,立刻把当前终端的操作控制权还给你。
于是,我把昨天那条单纯的启动命令,升级成了“极客究极防断版组合拳”:
# 拆解:前面加 nohup 防强杀,最后面加 & 强行扔进后台nohup python3 spider.py &敲下回车,屏幕上并没有像往常一样狂刷进度日志,而是极其冷静、高深莫测地吐出了一行系统回执:
> [1] 23456> appending output to nohup.out系统吐出了两个极其重要的信息:[1] 是后台作业号,23456 是这个进程的真实 PID。并且终端立刻弹出提示符,我可以继续敲别的命令了。
这就完了?它现在去哪了?
极客原理解析与防呆避坑指南
1. 日志去了黑洞吗?(nohup.out)
既然程序被扔到了看不见的后台,那它原来要在屏幕上打印的那些极度关键的报错和抓取进度去哪了? 别慌!细看刚才的第二句回执 appending output to nohup.out。 原来,nohup 极其贴心地在当前目录下,自动为你生成了一个名叫 nohup.out 的文本账本。你程序吐出的所有前台废话和报错,全都被悄悄塞进了这个文件里。 你想看进度?随时敲一句我们在后续会讲到的神技 tail -f nohup.out,就能像看直播弹幕一样看着后台的进度。
2. 怎么结束它的生命?
当你后悔了,或者爬虫跑出致命 Bug 陷入死循环疯狂占用 CPU 时,你怎么关掉一个在后台看不见摸不着的程序?
还记得 nohup 刚启动时吐给你的那串数字 23456 吗?那就是它的底层身份证号(PID)。直接祭出我们在 Shell_V25 学过的终极斩杀术:kill -9 23456它就瞬间在后台彻底消失了。
3. 防呆第一铁律:退出姿势极其重要
敲完 nohup xxx & 之后,千万不要直接用鼠标去点窗口左上角的红色大叉强制关闭终端!在很多系统的配置下,如果你暴力关闭终端,有些 nohup 任务依然会被意外干掉。
正确的极客退出姿势是:敲入 exit 命令回车,或者按快捷键 Ctrl + D 正常注销终端。只有当你看到 logout 字样时,程序才算真正平稳地交接给了系统后台孤儿院,你再去合盖子或拔网线就绝对万无一失了。
有了这张免死金牌,我再也不用像盯贼一样守在电脑前了。让机器去打苦工,极客只负责安心验收。
本期知识库沉淀:跑长耗时任务怕断网断电导致中断白跑,用 nohup 你的命令 & 将程序挂入后台免死运行,输出日志会自动保存在当前目录的 nohup.out 中。
夜雨聆风