1. 学习Linux指令的正确姿势:从"背命令"到"搭积木"
先问大家一个问题:你是不是也收藏过《Linux命令大全》这类文章,收藏完就再也没打开过?我自己刚入行时干过一模一样的事,甚至打印过一份几百条指令的清单贴在工位上,结果该不会的还是不会,遇到服务器出问题照样手忙脚乱。
后来带过不少新人,才慢慢想明白一件事:Linux指令这个东西,靠"背"是背不出来的,你得靠"用"。真正让你从入门到能扛事儿的,不是你记住了多少条命令,而是你脑子里有没有建立起一套"发现问题→拆解问题→用指令组合解决问题"的思维链路。指令本身只是积木,怎么搭积木才是核心能力。
这篇内容适合谁?刚接触Linux没多久的学生、准备转行做运维的朋友、已经做了几年桌面运维想往上走的人,当然还有正在准备Linux面试的求职者。我会尽量把指令背后的"为什么"讲明白,而不是简单罗列一堆命令让你去背。
1.1 为什么你学了半年Linux,遇到故障还是大脑空白
我观察过很多新手处理故障的状态:网站打不开了,第一反应是百度"Linux网站无法访问怎么办",然后照着教程一条条试,试完不行再换一篇。整个过程没有任何逻辑可言,像是盲人摸象。
问题出在哪?出在他们从来没有想过一个问题:Linux系统里,每一类信息都存在固定的"地方",你只需要学会到这些地方去"问话"。
举个例子,服务器突然变得很卡。新手的第一反应通常是"重启大法好",但重启完问题还在。而一个合格的运维会这样拆解:
- 卡,到底是卡在CPU、内存、磁盘、网络哪一块?
- 如果是CPU,是哪个进程吃掉的?
- 如果是磁盘,是空间满了还是IO读写频繁?
- 如果是网络,是带宽跑满还是连接数爆了?
你看,这么一拆,问题就变成了四个小问题,每个小问题对应几条指令:CPU看top、内存看free、磁盘看df和iostat、网络看ss和iftop。你不需要背一百条命令,你只需要掌握这四五个"问话"工具,就能把一个模糊的"卡"字,变成一个明确的"就是某个Java进程把CPU吃满了"的结论。
这个过程,我管它叫"搭积木"。单个指令是一块积木,解决问题的思路是把积木拼起来的图纸。没有图纸,积木再多也是废料。
1.2 管道的价值:先学会"组合拳",再谈"单招"
有朋友可能会问:那是不是把top、free、df这些学熟了就够了?不够。因为真实场景里,你手里拿到的是几十上百个进程、几千行日志,你需要的是"筛选"和"定位"的能力,而不是把它们全列出来。
这里就必须提到Linux里最伟大的设计之一:管道。符号就是一个竖线|,它的意思是:把左边命令的输出,交给右边命令继续处理。
我举一个最经典的组合,几乎每个运维都写过:
ps aux | grep java | grep -v grep | awk '{print $2, $3, $11}'这条命令干了什么?普通用户只看到一串字符,但老手看到的是四个步骤:
ps aux—— 把系统里所有进程列出来;grep java—— 只保留和Java相关的行;grep -v grep—— 去掉grep自己产生的那一行(因为grep也会作为一个进程出现在列表里);awk '{print $2, $3, $11}'—— 只输出PID、CPU占用率、命令行这几列。
这就是典型的"搭积木"。每一步做一件简单的事,组合起来就完成了一个"定位JVM进程并看它的CPU占用"的操作。
再举一个和生活更贴近的例子:查出系统里按内存占用排序的前五个进程。
ps aux --sort=-rss | head -5--sort=-rss是让进程按物理内存从大到小排序,head -5只取前五行。你看,你不需要知道RSS是什么,你只需要理解"我想看什么→用什么参数让它排好序→截取前几条"这个思维路径。
所以我强烈建议初学者在练习指令的时候,不要一条条孤立地敲,而是尝试把多个指令串起来,强迫自己问:上一条命令的输出,能不能作为下一条命令的输入?一旦建立起这种"拼接"意识,你会突然发现,很多所谓复杂的运维操作,其实都是几个简单命令的组合。
1.3 遇到不会的命令,先靠这几个"问路"工具自救
还有一个特别重要的习惯:遇到不会的命令,别急着开浏览器搜。Linux系统本身就给你配好了几个"问路"工具,熟练使用它们,比收藏任何教程都有用。
man 命令名:查看命令的完整手册,内容最全,但排版对新手不友好。适合已经知道命令名、想看具体参数细节的场景。命令名 --help:快速查看命令的常用参数,日常使用频率最高的就是它。whatis 命令名:一句话解释命令是干嘛的。which 命令名:查看命令的可执行文件在哪个路径下,比如which nginx能帮你确认nginx装在哪。
我给自己的要求是:遇到没见过的命令,先--help;--help看不懂,再man;man还看不懂,才去搜教程。这个过程本身就是一种能力训练,因为你强迫自己先在系统内部找答案,慢慢地对命令的理解会越来越深,而不是永远依赖外部搜索。
再补充一个细节:很多命令的帮助信息是英文的,刚开始会劝退不少人。我的建议是别怕,看不懂的单词直接翻译,遇到两三次就记住了。你不需要成为英语专家,你只需要认得出"usage""options""example"这几个高频词就够了。
2. 夯实基础:这些常用指令必须形成肌肉记忆
如果说管道的思维是"图纸",那接下来这一章讲的就是最常用的"积木"。我不打算把Linux几百条命令全讲一遍,那不现实也没必要。我挑的是日常运维和面试中出现频率最高的八类指令,按场景分类,每个场景讲透几件最关键的事。
我的判断标准很简单:这些指令你在真实排障时大概率会用到,而且它们之间存在关联,单独学任何一个都不完整。
2.1 文件与目录操作:别只会ls和cd
很多人觉得文件操作嘛,不就是ls、cd、cp、mv、rm吗?是的,但只会这些,在运维场景里真的不够用。我挑几个工作中的高频场景说一下。
第一个是查找文件。服务器上配置文件遍地都是,你有时候只记得一个关键词,不记得完整路径。这时候find比翻目录快得多:
find /etc -name "*.conf" -mtime -7这条命令表示在/etc目录下找所有以.conf结尾的、最近7天内修改过的文件。为什么-mtime -7很有用?因为如果你今天改了某个配置导致服务异常,你大概率能在最近一两天的文件里找到它。
第二个是软链接。很多新手不理解什么是软链接,我用一句大白话解释:它就是一个"快捷方式",你打开它,实际上访问的是另一个路径的文件。运维里最常见的用法是两个:
ln -s /usr/local/nginx/conf/nginx.conf /etc/nginx/nginx.conf这样你就可以用固定的路径去访问实际存放的文件,目录结构怎么变都不影响访问者。还有一个经典场景是升级软件版本:新版本装在一个新目录里,旧目录的软链接指过去,系统无感切换。
第三个是删除和备份的"安全余量"问题。我在真实工作里见过太多人因为一个回车键把服务删没了。所以给你三条经验:
- 删除之前,先
ls看清楚当前目录,再执行rm。这个习惯能救你一命。 - 能用
mv到临时目录代替直接删除的,尽量不要用rm,这样后悔了还有退路。 - 批量删除之前,先
ls 要删的文件名确认匹配到了什么,再替换成rm执行。
我曾经因为一条rm -rf /usr/local/nginx/html /usr/local/nginx/conf少打了一个结尾的/,差点把整个nginx配置目录删掉。从那以后,凡涉及rm -rf,我都要先在前面加echo打印出来确认一遍路径,再真正执行。
2.2 进程与资源:top、ps、free、df怎么配合看
进程和资源排查,是Linux运维的核心中的核心。我把这块的常用指令整理成一组动作链,方便大家记忆:
| 排查目标 | 指令 | 关注什么 |
|---|---|---|
| CPU占用率高的进程 | top/ps aux --sort=-%cpu | RES、CPU列 |
| 内存不足 | free -h | available值 |
| 磁盘空间满了 | df -h | 各挂载点的Use% |
| 磁盘读写繁忙 | iostat -x 1 | %util,超过80%说明IO瓶颈 |
| 定位某个服务的PID | pgrep -f 服务名 | 输出PID |
这套动作链怎么理解?你可以把它想象成体检:先看整体的血压血脂(free、df),再聚焦到是哪个器官出了问题(top、ps),最后针对性地看某个具体进程的详细情况(pgrep + 进入/proc目录看细节)。
重点说一下free -h。很多人只看第一行的total和used,其实在CentOS 7及以上版本的系统里,真正要关注的是第二行的available。buff/cache占用的内存是可以被系统回收再利用的,所以就算used显示90%,只要available还充足,系统就不会真的内存不足。这个细节在面试里也是高频考点。
还有一个容易被忽视的现象:服务器CPU占用率长期不高,但系统响应却非常慢。这时候要警惕是不是IO瓶颈,而不是只看CPU。我处理过好几次类似的"假故障",数据库的慢查询日志没异常,磁盘iostat的%util却常年90%以上,一查是某天夜里一个全量备份脚本叠加了高峰期业务流量,把磁盘IO挤爆了。所以看问题不要只盯一个指标,CPU、内存、IO、网络四个维度至少要过一轮。
top这个命令也有使用技巧。默认每三秒刷新一次,你进入top后按P键是CPU排序,按M键是内存排序。你还可以按1查看每个CPU核心的使用率,判断是不是有进程占用单核。这些交互按键,才是top真正的威力所在。
2.3 权限模型:rwx和数字权限怎么记才不容易混
权限这块,很多新手是死记硬背状态,碰到chmod的数字就想翻书。其实你只要理解"r=4、w=2、x=1,三者相加"这个规则,后面就再也不会忘。
| 权限 | 数字 | 说明 |
|---|---|---|
| r | 4 | 读,可以查看文件内容/列目录名 |
| w | 2 | 写,可以修改文件/增删目录中的文件 |
| x | 1 | 执行,可以运行脚本/进入目录 |
常见的组合:
chmod 755 file—— owner可读可写可执行,group和others可读可执行。这是大多数脚本和程序的默认权限。chmod 644 file—— owner可读可写,group和others只读。这是配置文件最常见的权限。chmod 600 file—— 只有owner可读可写,其他任何人不可访问。SSH私钥、密码文件这种敏感内容必须用600。
还有就是chown,它解决的是"这个文件归谁"的问题。很多服务启动失败,日志里会写Permission denied,十有八九就是文件所有者不对。举个例子,如果nginx的worker进程以nginx用户运行,但你给html目录的属主设成了root,nginx就读不了里面的静态文件。这时候一条指令解决:
chown -R nginx:nginx /usr/local/nginx/html-R表示递归,目录下所有子文件和子目录一起改。
还有一个我特别想提醒的点:尽量不要用root身份跑日常业务服务。我自己刚入行时图省事,全用root跑一切服务。后来遇到一个安全扫描发现服务器被植入了后门,排查发现就是某个服务以root权限运行,被利用后直接拿到了最高权限。从那以后,我凡是新部署一个服务,先建专用用户再跑服务,权限能少给就少给。这个习惯虽然不能立竿见影,但一旦出事,它能帮你把损失控制到最小。
su和sudo的区别也需要分清楚。su是切换到一个用户,通常需要输入那个用户的密码;sudo是临时以另一个身份(默认root)执行某一条命令,输入的是你自己的密码。生产环境里我几乎不用su切root,而是用sudo加白名单的方式,让运维同事能执行特定的管理命令,又不需要交出root密码。哪个更安全,一目了然。
3. 运维实战:日常排查问题的指令组合拳
前面基础讲完,进入重头戏:真实故障排查。这一章我按"排查链路"来组织,每个链路是一组指令的组合,你照着走一遍,大部分问题都能定位到根因。
为什么强调"链路"?因为单条命令只能给你一个快照,而故障排查需要的是一个"逐步缩小范围"的过程。就像警察破案,不是拿一张照片满大街问,而是先看监控发现嫌疑人活动的区域,再缩小到街区,再锁定到个人。
3.1 服务起不来的通用排查链路
先说一个最最常见的场景:新部署了一个服务,systemctl start却没成功。新手往往反复start、反复status,就是看不到有效信息。正确的排查步骤应该是这样:
第一步,看服务的当前状态和错误信息:
systemctl status nginx如果status里信息不够明确,立刻看日志。在systemd体系下,运行journalctl是拿到服务详细日志的最快方式:
journalctl -u nginx -n 100参数-u指定服务名,-n 100表示只看最近100行。你大概率能看到类似Address already in use、Failed to parse configuration之类的报错,问题基本就定位了。
第二步,确认端口和进程是不是真的没起来。
有些时候systemctl状态看起来是active,但服务实际不可用,这可能是端口没监听,也可能是进程僵死。这时候用:
ss -tlnp | grep 80看80端口有没有LISTEN状态的进程。没有就说明nginx没真正起来;有但不通,那就是防火墙或网络层面的问题。
第三步,针对原因做核实。
比如报错是Address already in use,说明端口被占用了。那就需要找出是谁占的:
lsof -i :80或者用ss -tlnp直接看PID,再用ps -p PID -f看是谁。这个链路走下来,基本十次有八次能锁定问题。
第四步,千万不要忽略配置文件语法检查。
nginx这类服务,很多启动失败是配置写错了。它有一个特别好的习惯,支持先校验再reload:
nginx -t如果输出syntax is ok再执行systemctl reload nginx。这个习惯帮我避免过很多次"改完配置reload后服务挂了"的惨剧。其他服务也类似,比如bind有named-checkconf、sshd有sshd -t,部署前先跑一遍语法检查,成本几乎为零,收益却非常大。
3.2 日志分析:从几百MB日志里快速捞出关键信息
日志是运维排查问题的第一手证据。但服务器日志动辄几百MB甚至几个GB,你不可能一篇篇翻完。你需要的是一套"权力过滤"的手法。
我用得最多的组合是这套:
tail -1000 /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20这条命令拆开看:
tail -1000取最近1000行;awk '{print $1}'取出每行的第一个字段,Nginx日志里通常就是客户端IP;sort把相同的IP排到一起;uniq -c去重并统计出现次数;sort -rn按次数从大到小排;head -20只看前20个。
于是你就得到了一个"最近1000次访问里,哪些IP访问次数最多"的榜单。如果发现某个IP瞬间刷了几百次,基本可以判断是爬虫或者攻击尝试。
再比如,你想看最近一小时某个服务的报错是否和某个接口相关:
grep "ERROR" /var/log/app.log | grep "order-service" | tail -50先按级别过滤,再按服务名过滤,最后取最近50条。你看到的就只剩你要的那一小撮日志,排查效率直接翻倍。
我做运维的朋友常开玩笑说:日志就像冰山,你看到的内容再少,也只能相信你过滤出来的那部分。一套好的过滤组合,等于给了你一杆捞网,能从汪洋大海里精准捞出鱼来。
3.3 网络问题定位:ping通了不代表服务是好的
网络排查是另一个高频场景。但这里有一个很大的认知误区:很多新手一遇到"网站打不开"就ping一下,发现能通就说网络没问题。实际上,ping通只能说明你和目标主机之间的三层网络是通的,完全不能说明目标主机上的应用服务是好的。
我自己刚转运维那年就吃过这个亏。公司一个内部系统对外提供HTTP接口,业务方反馈"连不上"。我ping了一下IP,通了,就回复"网络正常,你们再试试"。结果对方把HTTP响应截图发过来,一片超时。后来一查,是防火墙只放行了ICMP,没放行TCP 8080端口,y轴是"ping通"、x轴是"业务不通",我根本不在一个维度上看问题。
正确的网络排查链路应该是这样的:
第一步,先确认目标端口通不通:
nc -vz 192.168.1.10 8080nc配合-vz会返回端口是否开放。也可以用telnet ip port,但nc更灵活,而且能在脚本里直接判断结果。
第二步,确认域名解析正不正确:
dig example.com +short或者用nslookup。这一步排查的是DNS问题。很多"网站突然打不开"的案子,最后定位到就是DNS解析异常。
第三步,用curl模拟HTTP请求:
想看到完整的响应头和耗时信息,可以用:
curl -v -I https://example.com/api/health-v打印过程细节,-I只拿响应头,-w '%{http_code} %{time_total}'可以再加上状态码和总耗时。如果响应很慢,再看看是不是后端接口本身耗时高,还是代理转发环节慢。
第四步,看本机的连接数和防火墙规则:
ss -tlnp iptables -L -n | grep 8080这几步走完,网络层面的问题基本能定位个八九不离十。我特别建议每个做运维的朋友都把这套链路练成"肌肉记忆",就像开车遇到红灯踩刹车一样不需要思考。
3.4 常用排查指令速查表
最后给一个我整理的高频速查表,大家可以直接打印出来贴工位上,遇到问题时对着表走流程:
| 场景 | 指令 | 判读要点 |
|---|---|---|
| 服务没起来 | systemctl status 服务名 | 看 active (running) 还是 failed |
| 看服务日志 | journalctl -u 服务名 -n 100 | 找ERROR、FATAL |
| 磁盘满了 | df -h | 看每个分区Use%是否接近100% |
| 文件占用大 | du -sh * | 在当前目录找占用空间最大的目录 |
| 内存不足 | free -h | 优先看available列 |
| CPU高 | ps aux --sort=-%cpu | head -5 | 找出CPU占用最高的进程 |
| 端口占用 | lsof -i :端口 | 看PID和进程名 |
| 连接数异常 | ss -s | 看TIME_WAIT等状态统计 |
| 动态追踪进程 | strace -p PID | 查看系统调用,排查进程卡住原因 |
最后一行的strace可能有点超纲,但我提一下:当进程出现诡异卡顿,常规手段查不出问题时,strace -p能告诉你进程在和内核聊什么,往往能一针见血地发现它卡在哪个系统调用上。这类"大杀器"不需要常用,但关键时刻能救命。
4. 高效进阶:从单机操作到批量管理
聊完了排查,再聊聊进阶。很多人在单机上已经很熟练了,岗位却卡在了一个尴尬位置:你懂Linux,但你管的服务器可能只有两三台,或者你还在靠"记笔记加手工敲命令"维护几十台机器。这个阶段真正要突破的,不是再多记一两条指令,而是从"用手操作"升级到"用工具管理"。
4.1 SSH免密登录:批量操作的第一步
Unix哲学里有一个很朴素的思路:如果你发现自己重复做的事情超过两次,就该考虑让它自动完成。运维里最典型的重复劳动就是"登录服务器敲命令"。
假设你有10台服务器,每次部署都要逐台ssh上去操作,光是输入密码的时间累积起来就非常吓人。所以你首先要解决的一件事:SSH免密登录。
ssh-keygen -t rsa -b 4096这会在你的~/.ssh/目录下生成一对密钥:公钥和私钥。私钥留在本机,公钥分发到目标服务器。
ssh-copy-id user@192.168.1.10执行后,下次登录就不再需要输密码了。原理不复杂,但是理解这个机制之后,你对"安全"和"便利"的取舍会有更清晰的认识:私钥是证明你身份的东西,丢了私钥等于丢了钥匙,所以私钥文件权限必须是600,这一点在前面权限章节讲过。
有了免密,你就能开始用循环批量执行命令了。比如给10台机器写同一段环境变量:
for ip in $(cat server_list.txt); do ssh root@$ip "echo 'export LANG=en_US.UTF-8' >> /etc/profile"; done虽然这已经很高效,但当服务器数量破百,循环脚本就会变得不好维护。这时候就该引入专门的自动化工具了。
4.2 从Ansible开始:让指令变成可控的"配置"
我建议刚进阶的运维朋友从Ansible入手,原因是它不需要在目标机器上装任何额外客户端,只要你已经能SSH登录目标机,就能跑Ansible。这比很多需要装Agent的方案轻量得多。
举个最直白的例子,给一批机器安装一个软件包并启动服务,手工操作要逐台登录,Ansible只需要一条命令:
ansible all -m yum -a "name=nginx state=present" ansible all -m service -a "name=nginx state=started enabled=yes"这里的-m是模块名,yum和service都是Ansible内置模块。你不需要写一行复杂的shell脚本,Ansible会自动处理目标系统的差异。
写Playbook(Ansible的编排文件)也不难,我第一次写的时候,感觉就是在写一份"机器执行的说明书"。比如下面这个三段式任务,把"安装nginx→拷贝配置→重启服务"串起来:
- name: setup nginx hosts: web_servers tasks: - name: install nginx yum: name: nginx state: present - name: copy config copy: src: /etc/nginx/nginx.conf dest: /etc/nginx/nginx.conf notify: restart nginx - name: start nginx service: name: nginx state: started enabled: yes你会发现,你在单机上手敲的那些指令,本质上就是在"管理一台机器的状态"。Ansible把这些指令抽象成了模块,让它们可以重复执行、跨机器执行。你不需要再关心目标机器上用的是哪一版yum还是apt,Ansible会把细节处理掉。
我自己的体会是,当服务器超过5台时,手工操作和Ansible的效率差距还不明显;一旦超过20台,Ansible的威力就体现出来了。这也是"高效进阶"这条路上非常关键的一步。
4.3 Docker和systemd:把"服务管理"变成"标准动作"
除了Ansible,另一个绕不开的进阶方向是容器化。如果你会看docker ps、docker logs这些指令,你的运维效率会比纯手工管理物理机高出一大截。
Docker出现后,很多人以为"运维只要会docker run就够了",其实不然。真正要理解的是:Docker把"环境差异"这个问题封装了。你在测试环境跑通的容器,丢到生产环境一样能跑,因为它自带了一整套运行时依赖。
看看这几个和docker相关的高频指令有多直观:
docker ps -a # 看所有容器,包括停掉的 docker logs -f container_name # 实时看容器日志,等价于tail -f docker exec -it container_name bash # 进入容器内部,排查问题 docker inspect container_name # 看容器配置和元信息注意,Docker容器里通常没有systemctl,因为容器本身不是一个完整的systemd系统。管理容器的"启停"操作你直接对docker下指令就好,宿主机的systemd只管到"dockerd这个守护进程拉起来"为止。
至于传文件、备份、定时任务这些,结合前面几章的内容你就知道该怎么做了。比如把容器内数据定期备份到宿主机的定时脚本:
0 3 * * * docker exec mysql_backup mysqldump -u root -p密码 数据库名 | gzip > /backup/mysql_$(date +%F).sql.gz这条crontab任务每天凌晨3点备份一次数据库,导出后立刻压缩。$(date +%F)会生成当天的日期字符串,方便区分备份版本。写定时任务的时候,我强烈建议先把脚本完整测试两遍再放入crontab,还要在脚本开头加上日志输出,否则哪天任务悄悄失败了,你很难第一时间发现。
4.4 软件部署的两种姿势:包管理器和编译安装
最后再补充一个进阶阶段绕不开的话题:装软件。很多新手喜欢在官网下载源码包编译安装,感觉"高端"。但我的建议恰恰相反:能用系统包管理器解决的,优先用包管理器。
yum install -y nginx # 或 apt install -y nginx包管理器最大的好处是:它自动处理依赖关系、自动注册systemd服务、后续升级打补丁一条命令搞定。你手软编译安装,不仅费时费力,后续的安全补丁也得自己跟进,出了漏洞很可能几个月都不知道。
什么是需要编译安装的场景?比如你安装的软件版本在系统仓库里太旧,你需要新特性;或者你需要定制编译参数,比如把PHP的某个扩展编进去。这时候源码安装才有意义。
还经常有人问我:安装MySQL、Redis、Python这些是编译好还是用包管理好?我现在的经验是:Redis用包管理器就够,MySQL看场景,Python建议用pyenv这类版本管理工具。每个软件都有自己的最佳实践,你不需要背下来,但装之前不妨花两分钟搜一下大家都在推荐哪种方式,比自己闷头编译半天省时省力得多。
而且,不管用哪种方式装完,都应该养成一个习惯:把安装步骤、版本号、踩过的坑记录在案。我自己有个运维笔记,每周更新一次,到年底回看的时候,你会发现自己处理问题的速度真的快了很多。
5. 面试与成长:Linux常用指令在真实工作中的考察方式
前面几章基本把"从入门到能干活"的路径讲完了。最后这一章聊点实在的:面试和职业成长。很多朋友问过我同一个问题:我看了一堆指令,面试时还是答不上来,是不是我看得不够多?
我的想法恰恰相反:你答不上来,不是你记得太少,而是你想得不够深。因为面试官真正想看的,从来不是你背了多少命令,而是你能不能把指令当成解决问题的工具来使用。
5.1 面试官真正想考的是什么
我在面试Linux运维岗的时候,很少会问"常用命令有哪些"这种开放性题目,因为答案太泛了。我更喜欢问场景题,比如:
“服务器CPU飙到100%,你如何排查?”
这道题如果对方直接回答“输入top”,我只能打及格分。我更期待听到的思路是:
“我会先top确认CPU占用最高的进程,再用ps aux --sort=-%cpu看进程的详细信息,确认是不是自己的业务进程;如果确认是正常业务,再结合strace -p PID看它在干什么;如果不是正常进程,可能是被入侵了,要赶紧隔离网络,然后检查启动项、计划任务,清理可疑文件。”
看到区别没有?在这个回答里,top只是起手式,真正让面试官眼前一亮的是后面的排查链路:能看到问题的不同类型,并有针对性地给出不同的后续动作。这就是我从第一章反复强调的"搭积木"思维的价值。
再比如另外一道老生常谈的题:“磁盘空间满了,你怎么办?”
一个会思考的面试者会这样回答:
“先用df -h确认哪个分区满了,再用du -sh /*从根目录开始逐层排查,找到占用最大的目录和文件。如果发现是日志文件太大,就考虑清理历史日志;如果是数据增长过快,就需要考虑日志切割、扩容磁盘等手段。特别要注意的是,rm掉文件之后,如果还有进程持有该文件的句柄,空间并不会立刻释放,需要确认lsof找到这些进程并重启他们。”
你看,一个简单的“磁盘满了”问题,因为引入了“明明删了文件但空间没释放”这个实际经验,回答的深度一下子就上去了。这背后靠的还是经验积累,不是临时背题能背出来的。
5.2 遇到不认识的指令,怎么自保
还有一个我特别赞赏的习惯:承认自己不知道,但能明确说出"接下来我会怎么查"。这比硬着头皮瞎编强一百倍。
真实场景里不可能什么指令都见过。那么当你遇到一个没见过的指令时,正确姿势是什么?回到第一章讲的“问路”三件套:
whatis 不认识的命令名 man 不认识的命令名 不认识的命令名 --help如果系统里根本找不到这个命令,那大概率它不在你的PATH环境变量中,或者根本没有安装。这时候可以用yum provides 命令名搜一下哪个软件包会提供它,也是一种快速定位的方式。
更重要的是,你要把“查资料”本身变成一套高效流程。我自己的做法是:先在系统文档和--help里找答案,确认关键参数;如果还不明白,直接搜网络上的博客和官方文档。搜的时候带上"版本号和错误码",比如“nginx 502 bad gateway centos7”,比搜“nginx报错”更容易命中有效信息。
5.3 从“会敲命令”到“能解决问题”,中间就差这一步
最后说点掏心窝子的话。
我做运维这些年,一个最大的体会是:指令只是载体,真正值钱的是解决问题的思路。你收藏一百篇命令大全、背下一千条指令,遇到故障不会用,它们就只是躺在那里的文字。反过来,你平时多动手、多折腾,哪怕只掌握五十条常用指令,但每条都能在正确的地方发挥价值,你就能扛起一个服务端的稳定运行。
我建议每个刚入行或还在学习期的朋友,都做这样几件事:
- 建一个自己的命令笔记。不要Copy网上的命令大全,而是把自己实际用过的指令记录下来,标注适用场景和踩过的坑。一年以后,这本笔记就是你最值钱的资产。
- 定期复盘故障。每次处理完一个线上问题,写一段复盘笔记,不需要多长,三五行就够,重点是写清楚“根因是什么”“用了哪些指令定位”“以后怎么预防”。
- 有意识地练习“拆解思维”。看到一个故障描述,先问自己这个问题可以拆成几个小问题,每个小问题需要查看哪些指标。这个习惯对面试和实际工作都极其有帮助。
- 不要怕折腾测试环境。自己搭几台虚拟机,主动制造各种故障,练习排查。你在根目录删一个系统文件、把磁盘写满、把一个服务的配置改坏……这些模拟把故障都处理过一遍,以后真在线上遇到了,你就不会慌。
讲得再多,也不如自己动手敲一遍。Linux这条路上,最快的成长路径从来不是“多背”,而是“多折腾”。你把指令用熟了,把故障扛过几轮,把自动化工具玩顺了,再回头看当初那个对着man手册发愁的自己,真的会有一种“轻舟已过万重山”的感觉。
顺带提一句,我最近在自己服务器上折腾了一套“一键巡检脚本”,核心逻辑也不复杂,就是把前面章节讲的那些指令——df、free、uptime、ss、journalctl——串起来,定时执行并把结果汇总成一份简明报告发到自己的邮箱。工具不在多,能把常用的那几十条指令用到极致,就已经比很多人强了。
希望这篇内容能帮正在Linux入门或者进阶路上的朋友少走一些弯路。如果大家有一些自己踩过的坑,或者特别想了解的话题,也欢迎随时交流,下次可以继续展开聊聊。