很多人都问过我同一个问题:Linux 命令那么多,到底该怎么记?我的回答通常是——先别急着背,你试着把面前那台服务器当成一位等着看病的患者,命令就是你的听诊器、血常规报告单和手术刀。今天这篇是“医疗视角下的 Linux”系列第二篇,主题就是命令手册。上一篇我们聊了把整个 Linux 系统理解成一具运行中的躯体,这一篇扎进具体命令里,把故障排查时真正派得上用场的命令,按“初诊—检查—诊断—治疗—复查”的流程重新过一遍。
这套看病人的思路对两类人尤其受用。一类是刚转行做运维的新人,看着满屏命令焦虑到睡不着;另一类是被线上问题折腾到神经衰弱的开发同学。当你看 uptime 像在测心跳,看 ps 像在拿血常规报告,看 journalctl 像在翻既往病历,你记下的就不是一串孤立的语法,而是一整套应对故障的肌肉记忆。命令本身不难,难得是你知道此时该掏出哪一件工具。
1. 先把思路理顺:为什么用医疗视角学命令
1.1 把故障当症状,命令就是诊断设备
我见过太多新人学命令的方式:照着命令大全从头抄到尾,抄完就忘,忘了再抄。这种方法的根本问题在于,命令是挂在“知识点”上的,而不是挂在“场景”上的。人的记忆对有剧情的东西特别友好,对列表的东西尤其健忘。你记不住-lntp三个字母的组合,但能记住“我想看看这个端口到底是谁在监听,像照 CT 一样给网络连接拍个片”。
医疗视角的本质,是把“症状”和“检查手段”对应起来。服务器卡了,这是主诉;CPU 高不高、内存够不够、磁盘堵不堵,这是生命体征;进程列表像血常规,网络连接像影像片子,系统日志像病程记录。每条命令都有自己的“科室归属”,你按科室去找工具,比按字母表去翻命令高效得多。
这套逻辑还有一个额外的好处:排查问题的思路会变得很线性。真正出故障的时候,最大的恐慌来源不是不会敲命令,而是不知道下一步该干什么。但如果你脑子里装着一条清晰的诊疗路径——先看生命体征,再查专项指标,然后定位病灶,最后处理收尾——每一步该用什么工具几乎是自动浮现的。
1.2 这本命令手册的正确用法
这一篇不是让你从头读到尾的字典,而是一张“按症状查命令”的速查地图。我建议你先完整通读一遍这篇,把命令和场景的对应关系混个脸熟,不需要记住参数细节。真到服务器出问题的时候,你回来翻对应章节,照着做就行。
我平时的工作习惯是在终端里建一个属于自己的命令速查笔记,按症状分门别类:CPU 高了看哪几条、内存不够看哪几条、端口不通看哪几条、日志太多看哪几条。下面这个表是我自己笔记的简化版,也是全文的核心脉络:
| 症状 | 首查命令 | 对应章节 |
|---|---|---|
| 系统整体卡顿 | uptime、top、free、df | 第 2 章 |
| 有异常登录/用户行为 | who、last、w | 第 2 章 |
| CPU 或磁盘 IO 异常 | vmstat、iostat | 第 2 章 |
| 进程异常或找不到进程 | ps、top -p | 第 3 章 |
| 端口不通/网络慢 | ping、ss、traceroute | 第 3 章 |
| 进程卡死不响应 | kill、strace、lsof | 第 3、4 章 |
| 服务起不来/重启失败 | systemctl、journalctl | 第 4、5 章 |
| 日志排查 | journalctl、tail -f | 第 5 章 |
我自己踩过最大的坑,就是早期排查问题时东一榔头西一棒子:先无脑重启,重启不行再乱翻日志,折腾半天才发现是最基础的磁盘满了。后来老老实实按“先全局后局部、先硬件后软件、先系统后应用”的顺序走,效率提升不是一点半点。这张表就是那个顺序的浓缩。
2. 初诊与生命体征:判断这台机器还活没活着
2.1 生命体征四件套:uptime、free、df、top
病人推进来,不管什么病,先量体温、血压、心率、呼吸。Linux 服务器的生命体征四件套就是uptime、free、df、top。这套命令花不了十秒钟,但能让你对整台机器的状态有个基本判断。
uptime最核心的产出是最后的 load average 三个数字。很多人第一次看会懵:load average: 6.31, 4.12, 2.87,三个数到底看哪个?这三个数分别是过去 1 分钟、5 分钟、15 分钟的平均负载。判断标准不是笼统的“小于 1 就安全”,而是要除以 CPU 核心数:一台 4 核机器负载 4 才算满载,8 核机器负载 8 才算满载。我一般看趋势:15 分钟的数字低、1 分钟的数字持续往上窜,说明负载正在爬坡;反过来 1 分钟低于 15 分钟,说明可能在恢复。三个数字都高企不下,通常是长期性的资源瓶颈。
free -h是查内存的,注意一定要带-h,不然满屏的 KB 数字看得人眼晕。我见过太多人看到 used 数值很高就喊“内存不足要加内存”,其实要看的是 available 那一列。Linux 的内存管理机制决定了它会尽量把空闲内存拿去做缓存 buff/cache,这部分内存严格来说没有“浪费”,在需要时会自动释放给应用程序。真正该警惕的是 available 持续见底、并且伴随大量 swap 使用——那才是内存真的不够了的信号。
df -h查磁盘空间,看的是文件系统使用率。这里有一个高频坑:磁盘明明显示还有几十 G,应用却在报“No space left on device”。这是因为 inode 用满了,文件系统里的“索引卡槽”不够了,小文件太多会触发这个情况。所以df -h之外,养成顺手敲一下df -i的习惯,两个都看才能排除干净。
top是动态的体检仪,默认按 CPU 使用率排序,按 P 键按 CPU 排序、按 M 键按内存排序、按回车刷新。真正常用的反而是进去之后按几个键的事,单次快照我会用top -b -n 1把它打成静态档,方便截图和记录。顺便说一句,top里那个%CPU超过 100% 是正常的,多核环境下表示单个进程占用了多核资源。
2.2 查探视记录:who、last、w
服务器这种“重症病区”,最怕的是有不明身份的人混进来探视。who、last、w这三条命令就是查探视记录的。
who最简单,直接列出当前登录到系统的用户和登录来源 IP;w更进一步,能看到每个登录用户在跑什么命令,相当于实时监控你查房时大家都在干什么;last则翻历史账本,显示过往所有登录记录,包括登录时间、来源 IP、退出状态。
我排查安全事件时,第一步永远是敲last -n 20加who。有次一台机器被人爆破登录过,last里清清楚楚列着一串凌晨时段的陌生 IP,顺着 IP 再查cat /var/log/secure里的 sshd 日志,很快就确认了攻击来源。这些命令完全没有技术门槛,关键时刻却能把一个安全事故的排查时间从几天压缩到几十分钟。给别人排查问题时我也总先问一句:你查过登录记录吗?一半人会说没查。
2.3 分诊台:vmstat 和 iostat 判断要不要进抢救室
如果生命体征有异常,下一步是分诊——搞清楚瓶颈到底出在哪个子系统。这里我常用vmstat 1 5和iostat -x 1 3。
vmstat 1 5的意思是每 1 秒打一次点,连续打 5 次。重点看四类列:procs 下面的 r(运行队列长度)、cpu 下面的 us/sy/id/wa、swap 下面的 si/so、io 下面的 bi/bo。r 持续大于 CPU 核心数,说明任务排队严重;wa 数值高说明 CPU 在等磁盘干活,典型 IO 瓶颈;si/so 频繁跳动说明内存在和 swap 拼命换页,内存压力很大。这几组数据放在一起,基本能判断一个初步方向。
iostat -x 1 3看的是更细的磁盘状态。重点看%util、svctm、await几个指标:%util接近 100% 说明磁盘已经满负荷运转;await明显偏高说明每次 IO 请求都在排队等待。有一次客户报数据库写入慢,iostat一跑,%util直接 99%,await从正常的几毫秒飙到几百毫秒,立刻定位到磁盘性能瓶颈,而不是去无头苍蝇一样查 SQL。这个分诊环节最大的价值,是帮你把排查范围从“全系统”缩小到“某个子系统”,后面的事就有的放矢了。
3. 化验与影像:进程和网络两大诊断路径
3.1 血常规报告:ps 的正确打开方式
生命体征和分诊做完,如果还没定位到问题,就该上化验了。进程列表就是操作系统的血常规报告,而ps就是那份报告打印机。
最常用的几个姿势先说清楚。ps aux是 BSD 风格,能看到所有用户的进程,CPU 和内存占用也直接展示;ps -ef是 System V 风格,输出更像标准清单。两者核心信息差不多,选一个用顺手就行。真正高效的是组合 grep:ps aux | grep java找所有 Java 相关进程。但这里有个经典坑——grep 会匹配到自己的那条命令。我见过有人对着ps aux | grep nginx的结果疑惑“怎么有个 grep 进程也在跑”,那是 grep 命令本身的进程,加个grep -v grep过滤掉就行。
更精细的做法是用自定义列 + 排序一次拿到想要的答案。比如要找出最消耗 CPU 的 10 个进程:
ps -eo pid,user,%cpu,%mem,cmd --sort=-%cpu | head -11-e是所有进程,-o是指定输出列,--sort=-%cpu按 CPU 降序排。这比先ps aux再人工扫一眼高效得多,尤其是进程数量几百上千的生产服务器上。类似的,查线程可以加-L参数,查父进程关系用-o ppid。我个人最常用的组合是ps -eo pid,ppid,user,%cpu,%mem,etime,cmd --sort=-%cpu | head -20,etime 能看到进程已经跑了多久,对判断“这个进程是不是刚被拉起来的新面孔”很有用。
3.2 网络通断检查:ping、ss、traceroute 三张检查单
网络是排查里最容易让人上头的环节——本地没事、线上不通、或者两台机器互相访问超时,各种诡异现象都能遇到。我的习惯是按距离从近到远排三张检查单:先本地端口,再链路连通,最后路由路径。
先查本地端口监听。老派的netstat已经被ss取代得差不多了,处理上万连接时ss速度快太多。最常用的组合是ss -lntp:-l只看监听状态,-n不做域名反解显示数字端口,-t只看 TCP,-p显示是哪个进程在监听。直接回答“8080 端口有没有服务在听、是谁在听”。这个命令简直是端口占用问题的终极解药:
ss -lntp | grep 8080然后是链路连通性,ping依然是第一选择。看丢包率、看延迟的波动,连续 ping 几十个包能对链路质量有个基本判断。但注意,很多云服务器的安全组默认禁 ping,不通未必说明网络真有问题,别在这上面钻牛角尖。
如果 ping 通了但应用访问依然超时,或者丢包很规律,就该上traceroute看路径了。它会逐跳显示从本地到目标经过的每个路由节点,哪一跳开始延迟飙升,哪一跳出现星号超时,链路瓶颈往往一眼就能找出来。我排查跨机房访问慢的问题,靠traceroute定位到是中间某个云服务商的骨干节点在晚高峰拥塞,这种问题你再怎么折腾两端服务器都没用,换线路才是正解。
3.3 加做的专项检查:lsof 和 strace
常规检查做完还定位不了问题,就该上专项手段了。这里有两个神器,对应的场景差异很大。
lsof是“谁动了我的文件/端口/目录”的终极答案。lsof -i:8080查谁占用了 8080 端口;lsof +d /usr/local查谁打开了那个目录下的文件。做运维的人最崩溃的一个场景是:想卸载目录、删除文件,结果系统告诉你“设备或资源忙”,这时候lsof +d一查,立刻知道是哪个进程还攥着文件不放。这个命令上手极其简单,却总能在关键时刻把人从玄学排查中拯救出来。
strace则是内核级别的窥探镜,跟踪进程发出的每个系统调用。strace -p <PID>附加到一个正在运行的进程上,实时看它到底在干什么;strace -f连子进程一起跟踪。这玩意儿在“进程活着但不工作”的场景下特别好使。有次排查一个 Java 服务假死,CPU 不高、进程还在,但就是不响应请求,strace -p一挂上去,发现进程卡在某个文件读取的系统调用上反复重试,顺着文件路径查下去,发现是挂载的 NFS 存储失联了。这种问题,不看系统调用纯靠猜,根本猜不出来。
4. 手术与处置:进程管理和服务治理
4.1 麻醉与终止:kill 家族的信号语言
确诊之后就要处理了。处理进程,绕不开kill及其信号机制。很多新人不敢用kill,或者只会用kill -9,本质上是对信号了解不够。
kill -l可以列出所有信号。真正日常会用到的不超过五个:-1(HUP,让进程重新加载配置)、-15(TERM,请求进程正常退出)、-9(KILL,强制杀死)、-2(INT,模拟 Ctrl+C 中断)、-3(QUIT,让进程退出并生成核心转储)。这个顺序是有讲究的——信号强度从小到大,对应“劝退”到“强拆”的不同手段。
我处理异常进程的标准流程是:先kill <PID>(默认就是 -15),给进程几秒钟时间自己清理退出;不行再kill -9。为什么不能上来就kill -9?因为-15是给进程“处理遗言”的机会——保存状态、释放资源、通知上下游。直接-9相当于不给任何善后时间,可能留下脏数据、损坏的临时文件,甚至把共享资源锁在里面不释放。对于数据库、消息队列这类有状态的程序,无预警强杀是大忌。
批量处理可以用pkill -f <模式>或者killall <名字>,但这两个命令很危险,pkill -f匹配的是完整命令行而不是进程名,写错模式容易误杀无辜进程。我的习惯是先用pgrep -f <模式>看匹配到哪些 PID,确认无误再下杀手。另外,发现了僵尸进程(状态显示为 Z)不用太紧张,僵尸进程本身不再占资源,是它的父进程没来得及收尸,顺着 PPID 找到父进程处理即可,大部分情况等父进程重启后就会自动清理。
4.2 术后护理:systemctl 管的不只是启停
现代 Linux 上管理服务的核心工具是systemctl,但它能做的事远超“启动停止重启”。用医疗视角来看,systemctl管理的是整个住院流程——从入院登记到出院随访。
基础三件套是start、stop、restart,这个不用多说。但排查问题时的关键命令反而是systemctl status:它不只告诉你服务现在活着还是死了,还会带着最近几行日志、进程 PID、监听地址,等于一张浓缩的病历首页。服务异常退出时,状态里会有退出码和最近一次的失败原因,很多时候看这一屏就够定位了。
开机自启管理也在这里:systemctl enable是把服务登记到“长期住院名单”里,服务器重启后自动拉起;disable则是移除登记。新人最容易忽略的是daemon-reload——修改了 unit 文件之后不执行这个命令,服务配置不会重新读取,经常造成“我明明改了配置怎么不生效”的诡异事故。另外systemctl list-units --type=service --state=failed这条命令我每次排查服务器问题都会先跑一遍,看看有没有服务已经悄悄挂掉了——服务器上跑了一堆服务,靠肉眼巡检根本不现实,这条命令相当于全院巡诊。
4.3 修复病灶:从挂载到磁盘争用
服务的问题处理完,还有一些“外科手术”级别的操作,集中在挂载和文件系统层面。这一块最关键的原则其实是保守:能不动就不动,动手之前先备份。
挂载操作以 NFS 场景最常见,热词里有人搜“Linux 挂载 NAS 存储”,我多说两句。挂载命令的标准形式是:
mount -t nfs -o rw,hard,intr 192.168.1.100:/data/nfs /mnt/nfs加-o后面那一串是有讲究的:hard表示 NFS 服务端真出问题时客户端挂住等待重连而不是直接报错,intr允许挂住时用中断键退出。生产环境挂载远程存储时千万别图省事省略选项,否则服务端一抖动,客户端进程直接卡死在 IO 上,你连杀掉它的机会都没有,只能重启服务器。
磁盘空间处理上,除了删文件,还有一个方向是清理 docker 的堆积垃圾——docker system prune -a一键清理悬空镜像和停止的容器,经常一次就能释放几十 G。对了,顺序上先df -h确认确实满了,再du -sh /*从根目录逐层往下找占用大户,是最稳妥的,别凭感觉去猜哪个目录大。
文件系统修复(fsck)这个操作我放在最后提,而且要给你打一针预防针:非特殊情况不要在系统正常运行时跑fsck,尤其不能让它在挂载状态的文件系统上操作,轻则报错重则损坏数据。一定要修复,也是在单用户模式或救援环境下先卸载再检查。这不是命令难不难的问题,是敬畏心的问题。
5. 住院观察与病历管理:日志和权限
5.1 翻病历:journalctl 查出问题的时间线
系统出问题,最后都要回到日志来找时间线。现代 Linux 发行版基本都标配 systemd-journald,对应的查询命令就是journalctl。这一条命令用好了,排查效率至少翻倍。
最基础也最常用的几个用法:journalctl -u nginx只看 nginx 这个服务自己的日志,相当于调出某个患者的专属病历;journalctl -u nginx --since "2 hours ago"只看最近两小时的记录;journalctl -p err只显示 error 级别以上的严重问题,类比医生只关注危急值。这几个参数可以组合,比如我经常这么用:
journalctl -u myservice --since "30 minutes ago" -p warning -n 100意思是:看 myservice 最近 30 分钟内、warning 级别以上、最多 100 条的日志。这条命令已经成了我的肌肉记忆,每次服务异常的第一反应就是它。老派阅读方式tail -n 100 /var/log/messages或者/var/log/syslog也依然能用,但在过滤、组合查询方面,journalctl 的体验好太多。
看日志有个很反直觉但重要的习惯:先看时间和级别。我曾经花了半个小时研究一段异常堆栈,最后发现是三天前的过期日志在刷屏,真正的故障点在堆栈下面几百行。日志文件是流水账,不是论文,你必须先定位时间窗口,再按级别过滤,最后才读具体内容。
5.2 实时监护:tail -f 和 watch 的持续盯梢
排查告警或者观察服务启动过程时,需要持续盯着输出变化,这就用到两个工具:tail -f和watch。
tail -f是阻塞式的,文件新增内容会实时滚出来。排查服务启动失败时,我通常现场开一个终端挂着,然后去触发启动,实时看日志滚动,能清楚看到报错发生在哪一步。生产环境推荐用tail -F(大写 F),它跟-f的区别是文件被轮转切割后能自动重新跟进,老运维都知道这个细节,不然日志一滚你就盯着一份“死文件”。不想让历史日志刷屏可以用tail -f -n 0,只从当前时刻开始看新增内容。
watch则是定时刷新另一条命令的输出,适合盯指标。最经典的用法是watch -n 1 'ps aux | grep java'或者watch -n 2 free -h——每隔几秒刷新一次画面,相当于在监护仪旁边坐着连续观察。还有一个高频场景是“拷贝大文件想盯进度”,我习惯开一个watch -n 1 du -sh /目标目录,实时看目录体积在涨,心里就有底了。
这两个工具本身没有复杂度,但它们改变的排查节奏很重要:从“跑一次命令看一眼,再跑一次命令再看一眼”变成“挂在那里持续观察”,观察期一长,很多偶发问题就现形了。
5.3 探视权限管控:用户、组和权限的最小必要原则
服务器这个“病房”里的探视权限管理,就得靠用户和权限体系了。这块也是面试和实操的高频区。
新增一个用户的完整流程,很多人只知道useradd然后就卡住了。我的标准操作是一串:
useradd -m -s /bin/bash zhangsan passwd zhangsan-m会自动创建家目录并拷贝骨架文件,-s指定登录 shell。只建用户不设定密码,这个用户是登录不进去的。加进某个组用usermod -aG wheel zhangsan,注意-aG的-a是 append 追加,不带-a的usermod -G会把用户从其他组里全部踢出去,这个坑我见过不止一个人踩。
权限命令chmod和chown是配套使用的。最直观的数字表示法:755代表所有者读写执行、同组只读执行、其他人只读执行;644代表所有者读写、同组和其他人只读。对于普通配置文件,默认644;需要执行的脚本,默认755;绝对不要去设777,这在安全上等于敞开了大门。
sudo 提权配置我更愿意多提醒一句:编辑 sudoers 永远用visudo,不要直接改/etc/sudoers。visudo退出前会做语法检查,写错了还能挽救;直接改文件,一行语法错误就可能导致 sudo 全线崩溃,修复时你得进单用户模式,那心情真的叫一个酸爽。给用户授权也要按最小必要原则来:只需要重启服务的,就别给全权ALL=(ALL) ALL,单独授权那几条维护命令就够。
6. 实战推演:一次完整的患者抢救
6.1 场景:CPU 飙高、网站变卡的下午
聊了这么多命令,不串一遍总觉得不踏实。说个我真实处理过、且很有代表性的场景:某个工作日下午,业务方突然在群里反馈,官网访问特别慢,有些页面直接超时。我登录服务器的时候,心里的诊疗路径已经自动启动了。
第一步先看生命体征,uptime一敲:load average 已经到 7.8,而这台机器只有 4 核,明显超载。再看top -b -n 1 | head -20:一个 PHP 进程的 CPU 占用到了 300% 多,明显不正常。到这里,诊断方向已经从“网站慢”聚焦到“某个 PHP 进程有问题”。
6.2 诊断:顺着 PID 一路查下去
进程的 PID 出来后,我先用ps -eo pid,ppid,user,etime,cmd --sort=-%cpu | grep php确认这个进程的身份,发现它是通过php artisan queue:work起来的队列消费进程——一个在跑任务队列的 worker。到这里问题开始清晰了,肯定是某个队列任务在代码里写了个死循环或者调用了外部接口卡死了。
但它为什么卡死?我再上了专项检查strace -p <PID>。画面显示进程反复尝试连接一个外部 Redis 服务,连接超时,然后无限重试。顺着这个信息去查 Redis:ss -lntp | grep 6379,本地监听正常;redis-cli ping,报连接超时——网络上源 Redis 到应用机器之间出问题了。我又开一个终端看ping和traceroute,发现到 Redis 服务所在机房的链路丢包率接近 30%,这意味着这个 worker 根本不是业务逻辑有问题,是它依赖的 Redis 网络断了,导致每个任务都卡在网络等待上,CPU 空转。
6.3 处置与复盘:MVP 命令清单
按优先级处理:先把这个异常 worker 用kill -15温柔地停掉(它是无状态worker,可以安全重启),同时联系网络方定位链路问题;等网络恢复后,用systemctl restart phpxxx把 worker 拉起来,再用tail -F盯了几分钟日志确认队列消费恢复正常,最后systemctl list-units --state=failed确认没有连带挂掉的服务。
整个过程的 MVP 命令其实就那么几条:uptime、top、ps、strace、ss、kill、systemctl。没有一条是生僻命令,但按正确的顺序组合起来,就能把一个“网站很慢”的大模糊问题,一步步拆成“某个 worker 对这侧网络依赖断了”的精确结论。这就是我为什么坚持说,排查问题的关键是诊断路径,而不是命令本身。
这次救火给我最深的一个体会是:发现问题时最忌手忙脚乱,急着乱试命令。在终端里深呼吸一下,按流程走——先生命体征,再专项指标,最后定位病灶——90% 的问题都套得进这个框架里。你手中的命令其实一直够用,缺的是一个稳定的排查节奏。
7. 写在最后的一点手艺活
这篇更像是一张地图,把散落的命令挂到了一条清晰的诊疗脉络上。最后分享几个纯粹来自实战的小经验,它们不会出现在任何命令大全里,但真的能让你少掉几根头发。
第一,永远给重要操作留退路。生产环境动手之前,先想清楚一个问题:这台机器我搞坏了,有没有办法还原?删除前先备份、重命名而不是直接删、修改配置前先复制一份.bak,这些习惯会潜移默化地救你无数次。
第二,命令学会了,要刻意练成“条件反射”。新人和老手的差距,很多时候不在知识量,而在于遇到问题时的第一反应。我建议新人自己搭一台测试虚拟机,故意把服务搞挂、把磁盘写满、把进程搞成僵尸,再自己一步步查出来修好。这个过程看起来很笨,但练过三次之后你就再也忘不掉这些命令了。
第三,善用自带文档,man是你的最后一道保险。参数记不清楚,man 命令名或者命令名 --help永远都在那里。真正的高手不是什么都记得,而是知道去哪里查。命令手册背不完也没关系,你脑子里存一张索引就够了,细节随用随查。
把服务器当病人看,把命令当工具使,把排查当流程走。这套方法我用了很多年,稳定可靠,希望你也能用得顺手。下一篇文章,我准备把系统启动流程和内核这几个平时没人敢碰的“深水区”拿出来聊聊,用同样的诊疗视角走一遍,到时候你会觉得这些东西也没那么可怕。