☰
Linux实战100例:从故障排查到脚本自动化的核心方法论
2026/10/8 2:17:17 网站建设 项目流程

简介:一套面向Linux入门学习者与日常运维开发人员的实战案例合集,以一百个经典应用场景为主线,覆盖网络调用命令、Apache参数配置、Linux错误代码解读以及常见运行故障的排查方法,适合对照练习、查阅并解决实际问题。整套资源共两百零四个文件,主要以一百九十五个网页案例与说明文档为承载主体,辅以三份PDF手册、两个实验压缩包、两个备用压缩包,以及文档和可执行辅助程序,压缩包整体约40.19MB,目录结构清晰,便于按主题模块检索。已有两千一百八十人学习下载。最大价值在于每个实例均呈现详细的功能调用过程与排错思路,从命令行使用到服务配置层层展开,既能帮助初学者理解系统运行机制,也能在遇到类似报错时快速定位并对照解决。另含系统化索引、经典参考文档与辅助工具,适合作为案头速查、完整练习样本及深入研读的备查材料。

1. linux实战100例到底在解决什么问题

如果你在搜索引擎里敲下“linux实战100例”,大概率不是想再看一遍ls、cd、cp的用法解释,而是已经在工位上被某个故障卡住、被某条命令的异常行为搞到怀疑人生了。这个标题代表的不是一百个孤立命令的罗列,而是一百次真实场景里的问题拆解——从系统启动异常到磁盘占满,从脚本定时任务不执行到进程间通信失败,每一例背后都是一条完整的“现象 → 排查 → 解决”链路。它面向的是那些正在做Linux运维、嵌入式开发、系统管理工作,或者准备Linux面试的人,核心价值是让你在遇到同类问题时,不用从零开始试错。

真正的实战能力不是背出来的,是踩坑踩出来的。一百个案例拆开看,覆盖的是高频命令的非常规用法、故障排查的标准姿势、以及脚本编写里的边界条件和隐蔽坑点,这些东西在手册和命令大全里都找不到答案。接下来的篇幅,我会按实际工作中最常见的几条主线把这些案例拆开讲:哪些命令最值得深挖、故障怎么定位、脚本怎么写才不容易翻车、以及面试官真正想考察的是什么。

2. 命令实战里的优先级:先救活系统,再优化性能

很多人学Linux命令是从“常用命令大全”开始的,把top、df、ps背得滚瓜烂熟,但真上了生产环境,出了问题依然不知道从哪下手。原因很简单:你背的是命令本身,而不是命令适用的场景。一百个实战案例里最值钱的,是按“先活着、再查因、后优化”的顺序把命令串起来用的能力。

2.1 系统负载异常时,先看的不该是top

服务器响应变慢,大多数人的第一反应是敲top看CPU占用率。这是一个典型的思维误区。CPU跑满只是表象,真正的原因可能是磁盘I/O瓶颈、内存不足触发swap抖动、或者是某个进程在疯狂读写文件。正确的第一步是用uptime看负载均值,再配合vmstat 1 5观察r(运行队列)和wa(I/O等待)两个指标的变化趋势。

# 每1秒采集一次,共采集5次,观察r和wa列 vmstat 1 5 # 如果wa持续偏高,说明磁盘I/O是瓶颈 iostat -x 1 5

逻辑说明:vmstat的r列代表等待CPU的进程数,wa列代表CPU花在等待磁盘I/O上的时间百分比。当r远大于CPU核心数时,说明计算资源不够;当wa居高不下时,CPU其实在空转等磁盘,这时候你换再好的CPU也没用,得先处理存储。iostat -x里的%util接近100%基本可以确认磁盘阵列或单盘已经达到上限。

参数说明:vmstat后面第一个数字是采样间隔(秒),第二个是采样次数。实际排查中建议用1 5起步,不要用默认的一次性输出,因为负载是动态的,单次快照看不出趋势。iostat需要 sysstat 包,装好后-x参数会输出扩展信息,1 5同样是秒数和次数。

2.2 磁盘满了但df显示还有空间,问题出在哪

这是实战里非常经典的一类“翻车”案例:应用报错说磁盘已满,但你执行df -h一看,根分区明明还有十几个G。真正的元凶通常是文件被进程打开后删除了,但进程没退出,占用的空间没有被释放。这时候df是查不出问题的,要用lsof看已删除但仍被占用的文件。

# 找出所有已删除但仍在被进程占用的文件 lsof | grep deleted # 定位到具体进程后,确认进程PID和文件路径 lsof -p PID | grep deleted

逻辑说明:Linux下删除文件的本质是解除目录项的链接,但如果文件已经被某个进程打开,内核里的文件索引节点仍然存在,磁盘空间要等进程关闭这个文件描述符才会真正释放。lsof输出里的deleted标记就是这类文件的特征。常见的处理方式有两种:重启相关进程,或者用> /proc/PID/fd/文件描述符号清空文件内容,前者适合维护窗口内操作,后者适合不能中断的服务。

参数说明:lsof不带参数会输出所有打开的文件,量非常大,生产环境建议直接管道过滤。grep deleted是关键词匹配,有些老版本可能显示为(deleted),搜索时要注意。另外,用/proc/PID/fd方式清空时,必须先确认文件描述符号指向的是目标文件,别清错了对象。

2.3 查看端口占用时,netstat和ss怎么选

新装的系统上你可能发现netstat找不到了,这不是系统变弱了,而是ss已经把它替换掉了。ss直接读取内核的 socket 信息,速度比netstat快一个数量级,在处理大量TCP连接时尤其明显。一百个案例里如果只记一个查端口的命令,我推荐ss。

# 查看所有监听中的TCP端口及其对应进程 ss -lntp # 查看某个端口的连接情况,比如8080 ss -tunap | grep 8080

逻辑说明:-l只看监听状态,-n不做域名反解(否则会卡在DNS查询上),-t指定TCP协议,-p显示进程信息。第二行的-u加上UDP,-a表示所有状态。实际排查时,如果某个端口连不上,先看LISTEN状态是否存在,再看有没有SYN_SENT堆积,后者通常指向防火墙或对端服务异常。

参数说明:-p参数需要 root 权限,普通用户执行会看不到进程名。另外,ss的-a是显示所有 socket,不是 older 版本netstat -a那样会同时输出路由表。这个细节踩过的人不少,输出内容差很多。

3. 故障排查实战:像审案一样看日志和状态

运维故障案例看得多会发现一个规律:大部分“离奇”问题,最后都能在日志里找到答案,只是你没找对地方,或者没找对时间点。故障排查是一场有方法的侦探工作,顺序比命令更重要——先说现象,再锁范围,最后看日志验证,而不是东敲一条命令西翻一个文件。

3.1 系统启动异常时的排查路径:从内核到服务

服务器重启后起不来,或者起来后某个服务状态异常,这是生产环境里压力最大的场景之一。排查路径有一个固定顺序:先确认引导阶段有没有报错,再看系统日志里内核和服务的记录,最后看目标服务自己的日志。很多人一上来就去翻/var/log/messages,方向错了。

# 查看最近一次启动的内核日志,重点看硬件初始化和文件系统挂载 journalctl -b -p err # 检查关键服务的当前状态和最近几次重启记录 systemctl status sshd systemctl list-units --failed

逻辑说明:journalctl -b表示本次启动的日志,-p err过滤出错误级别及以上的记录。如果内核层面有硬件无法识别、文件系统挂载失败,这里会直接暴露。systemctl status sshd不仅显示当前状态,还会列出进程的最近日志和主进程PID。list-units --failed能快速找出所有启动失败的服务,比一个一个status查效率高得多。

参数说明:-b可以加数字,比如-b -1看上一次启动的日志,这个在对比“上次能起来这次起不来”时特别有用。有些系统用的是 rsyslog 而不是 journald,那就要改看/var/log/messages和/var/log/syslog,判断方法是执行systemctl status rsyslog确认是否在跑。

3.2 服务莫名其妙被杀死:先查OOM还是先看dmesg

应用进程运行几天后突然消失,systemctl status显示inactive (dead),重启后又恢复正常。这种情况大概率不是服务自身崩溃,而是被系统的内存回收机制杀掉了,专业叫法是 OOM Killer。但很多人习惯直接去调服务的超时时间,这是舍本逐末。

# 查看内核环形缓冲区,找OOM Killer的杀进程记录 dmesg -T | grep -i "killed process" # 确认系统内存压力和swap使用情况 free -h cat /proc/meminfo | grep -i commit

逻辑说明:OOM Killer 是 Linux 内核在物理内存耗尽且 swap 不足时,被迫选择牺牲进程来释放内存的机制。杀掉哪个进程由oom_score决定,这个分数和进程占用内存量、运行时间、优先级都有关系。如果被杀的恰好是你的关键服务,根源往往是另一个进程把内存吃光了,单纯调大服务自身的内存限制治标不治本。

参数说明:dmesg -T里的-T是把时间戳显示成人类可读格式,不加热参数显示的是开机秒数,排查时对不上出事时间点,很容易误判。free -h里重点看available而不是free,因为 Linux 会主动把空闲内存用于缓存,free很小不代表内存不足,available才是真正可分配的量。

3.3 网络排查的黄金命令组合:ping不一定是第一步

两台机器之间通信失败,菜鸟先 ping,老手先确认自己的网卡、IP和路由对不对。因为 ping 不通的原因太多了:对端禁ping、中间防火墙策略、自身路由配置错误、DNS解析异常。把排查顺序定成“自底向上”,每层验证一步,才能快速缩小范围。

# 第一步:确认自己的网络配置 ip addr show ip route show # 第二步:验证到网关的连通性 ping -c 3 网关IP # 第三步:确认目标端口是否可达(比ping更可靠) nc -zv 目标IP 端口

逻辑说明:ip addr show确认网卡有IP且状态是 UP,ip route show确认默认路由存在。这两步做完了,本地网络基础就是健康的。接着 ping 网关,能通则说明二层三层没问题。最后用nc -zv指定端口测试,是因为很多故障是“能ping通但端口不通”,防火墙、服务未启动都会导致这种情况。

参数说明:ping -c 3里的-c表示发送几个包就退出,不加的话会一直ping下去,脚本里跑批处理时很容易把人卡住。nc的-z是扫描模式只检测端口是否开放不发送数据,-v输出详细信息,有些精简系统没装 netcat,可以用timeout 3 bash -c "</dev/tcp/目标IP/端口"替代,效果一样。

4. 脚本实战:把重复运维变成一句话的稳妥写法

一百个案例里如果有一半涉及 Shell 脚本,剩下的那一半也值得你用脚本去解决重复操作。但写脚本的门槛不在语法,在于你得先想清楚边界条件:文件不存在怎么办、命令执行失败怎么办、传进来的参数是空值怎么办。这些没处理好的脚本,就是生产环境里一颗颗定时炸弹。

4.1 日志清理脚本:先写保护再写删除

清理日志是最常见的脚本需求,也是最容易写错的脚本。很多人上来就写find /var/log -type f -mtime +7 -exec rm -f {} \;,跑完才发现把正在被进程写入的日志删了,或者误删了别的目录下的同名文件。正确的写法是先做保护,再做清理,最后留审计记录。

#!/bin/bash # 日志清理脚本:保留7天,超过7天的压缩或删除 LOG_DIRS="/var/log/nginx /var/log/app" RETENTION_DAYS=7 for dir in $LOG_DIRS; do if [ ! -d "$dir" ]; then echo "$(date '+%F %T') WARN: $dir 不存在,跳过" >> /var/log/cleanup.log continue fi # 只处理 .log 结尾的文件,避免误删其他类型 find "$dir" -type f -name "*.log" -mtime +$RETENTION_DAYS -exec rm -f {} \; echo "$(date '+%F %T') INFO: cleaned $dir" >> /var/log/cleanup.log done

逻辑说明:脚本先检查目录是否存在,不存在就写告警日志并跳过,避免因为路径配置错误造成后续命令全部扑空。find命令里加了-name "*.log"是第二层保护,防止目录下出现非日志文件被误删。-mtime +$RETENTION_DAYS表示修改时间超过7天的文件,注意是+号,没有的话含义完全不同。每步操作都往审计日志里记录,出了故障能追溯执行过程。

参数说明:$LOG_DIRS用空格分隔多目录,如果要支持带空格的路径,需要改成数组写法。-mtime +7和-mtime 7的区别是前者匹配超过7天的,后者匹配恰好7天的,少一个符号结果天差地别。-exec rm -f {} \;里的分号必须转义,这是 find 语法里的固定要求。

4.2 批量重命名文件:让脚本自己先演练一遍

用 Shell 重命名文件这个需求,从热词搜索量就能看出它有多高频。mv命令本身很简单,但批量重命名时一旦出同名覆盖、特殊字符截断这类问题,后悔药都找不到。我一般会先让脚本输出将要执行的命令清单,人工确认无误后再真正执行,这个习惯帮我避免过好几次血泪教训。

#!/bin/bash # 批量重命名:把当前目录下的 *.txt 改为 *.bak DRY_RUN=${1:-true} # 第一个参数,默认只演练不实际执行 for file in *.txt; do # 文件不存在时,通配符会原样输出,这一步过滤掉 [ -e "$file" ] || continue new_name="${file%.txt}.bak" echo "mv $file -> $new_name" if [ "$DRY_RUN" = "false" ]; then mv "$file" "$new_name" fi done

逻辑说明:DRY_RUN变量控制执行模式,默认只打印不执行,参数传false才真正重命名。核心保护有两处:第一行[ -e "$file" ] || continue解决了 Shell 通配符没匹配到文件时会把*.txt当字面量传进来的问题;${file%.txt}是参数扩展,从末尾删掉.txt后缀再拼接.bak,比用sed处理更安全,因为sed对文件名里的特殊字符有额外的转义负担。

参数说明:脚本里用到的${file%.txt}是 Shell 内置的参数扩展语法,%表示从右往左匹配最短、%%是最长,这里用单%就够了。[ -e "$file" ]里的引号不能省,否则文件名带空格时整个判断会报错。DRY_RUN=${1:-true}是给第一个参数设默认值,传参方式类似./rename.sh false。

4.3 定时任务不执行的三个隐蔽原因

脚本写好了,crontab 也加上了,结果到点它就是不跑。这类问题在运维故障案例里出现频率极高,原因翻来覆去就那么几个:脚本没有可执行权限、脚本里的命令用了相对路径、环境变量和你在终端里不一样。其中环境变量不一致是最坑的,因为终端里测试一切正常。

# 在脚本开头显式声明所需环境 #!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin # 脚本内统一使用绝对路径操作文件 LOGFILE=/var/log/myscript.log echo "$(date '+%F %T') script started" >> "$LOGFILE"

逻辑说明:cron 执行脚本时用的 Shell 环境极其精简,PATH可能只有/usr/bin:/bin,你脚本里用到的命令如果装在/usr/local/bin下就会直接报 command not found。解决办法是在脚本开头显式export PATH,把常用路径都加进去。LOGFILE用绝对路径是为了防止 cron 的工作目录和预期不一致,它默认是用户的家目录,不是脚本所在目录。

参数说明:export PATH的覆盖写法是按实际环境调整的,生产机器装了什么路径就写什么,不要照抄。cron 里执行脚本时建议用完整路径:30 2 * * * /opt/scripts/cleanup.sh >> /var/log/cron_cleanup.out 2>&1,把标准输出和错误输出都重定向到文件,排查时可查可证。2>&1的顺序不能写反,2>&1和>&2含义不同。

5. 避坑手册:五个让我复盘一整晚的实战教训

实战里踩过的坑,每一条都比书上讲的更深刻。这一章不按功能分类,就写那些让我熬夜排查、最后发现原因的教训,希望能帮你少走同样的弯路。

5.1 df显示根分区100%,但du统计不到大头文件

现象:告警说磁盘快满了,但du -sh /算出来所有文件加一起也没到90%,磁盘空间“凭空消失”。

原因:有进程打开了一个已被删除的大文件,文件占用的空间不计入任何目录的du结果,但依然占据磁盘块。这种“幽灵文件”是磁盘满却找不到元凶的经典情况。

解决:用lsof | grep deleted找出占用进程,然后根据业务决定重启进程还是用> /proc/PID/fd/N清空。我曾经因为没查这个,傻乎乎地对根目录执行了du -sh *逐层排查,浪费了近两个小时。

5.2 端口明明在监听,但外部就是连不上

现象:ss -lntp显示服务在0.0.0.0:8080监听,本机curl localhost:8080正常,从另一台机器访问就超时。

原因:系统防火墙(firewalld 或 ufw)默认挡掉了外部访问。本机能通是因为 loopback 接口通常不受防火墙入站规则限制,给你造成“服务没问题”的假象。

解决:先systemctl status firewalld确认防火墙状态,再按需放行端口:firewall-cmd --permanent --add-port=8080/tcp && firewall-cmd --reload。如果是 ufw,则ufw allow 8080/tcp。教训是排查时一定从访问发起端逐层测,不要只看服务端本地状态。

5.3 脚本里用sudo执行命令,结果变量全是空的

现象:写了一个运维脚本,普通用户执行时报“sudo: command not found”,或者sudo后脚本里获取的用户变量变成空值。

原因:sudo 执行时会重置部分环境变量。更常见的是,你期待的$USER、$HOME和当前用户一致,但sudo后它们会被重置为 root 的对应值。还有机器上 sudo 命令本身所在路径不在默认 PATH 里。

解决:脚本开头直接export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。如果需要在sudo下保持环境变量,用sudo -E保留当前环境,或者显式在sudo命令里传参:sudo VAR=value ./script.sh。现在我的习惯是脚本内不依赖用户相关环境变量,需要时用id -un现场获取。

5.4 定时任务脚本里有中文注释,报crontab错误

现象:crontab -e 编辑时报错,或者任务不执行,系统日志里提示 crontab 文件里有非ASCII字符。

原因:crontab 文件对编码有要求,某些系统默认按 UTF-8 处理,如果你的终端编码是 GBK,写进去的中文注释在 cron 服务读取时就变成了乱码,导致整行解析失败。这个坑在初期机房用 Windows 终端连 Linux 时特别常见。

解决:crontab 文件里不写中文注释,一律用英文或拼音。脚本本身可以用中文注释,但文件编码必须是 UTF-8,且文件首行加#!/bin/bash。我个人的处理是脚本文件里标注编码:# -*- coding: utf-8 -*-,虽然 Shell 不强制,但对后续维护者是个明确提示。

5.5 磁盘性能“看起来”正常,但应用就是慢

现象:iostat 看 %util 只有 60%,top 看 CPU 也不饱和,可应用响应时间就是下不来。

原因:%util 是采样周期内设备有I/O请求的时间占比,它不代表设备满负荷运行。比如 SSD 处理请求极快,100% util 时实际吞吐还有余量;而机械盘在并发随机读时,%util 不高但每次寻道时间很长,队列深度(avgqu-sz)很高,这才是延迟高的真正原因。

解决:看iostat -x 1 5时重点看avgqu-sz(平均队列长度)和await(平均I/O响应时间),队列持续大于2、await超20ms就要警惕性能瓶颈了。不要再单看 %util 一个指标下结论,那是“黑匣子”式的判断方式。

6. 面试与进阶:把实战案例变成你自己的方法论

Linux面试题里常考的那些“实战场景题”,本质是考察你有没有形成一套稳定的排查方法论。面试官抛出一个故障场景,他真正想听的不是你背出的命令,而是你从哪个环节开始介入、每一步依据什么判断、最终如何收敛到根因。这和我前几章讲的排查思路是一致的:先看系统级状态,再锁进程级对象,最后验证和解决。

我建议你把做过的案例整理成自己的“案例-方法”映射表。每个案例记三行,第一行是现象(磁盘满了、服务挂了、端口不通),第二行是你用的第一条命令和判断逻辑,第三行是根因和最终解法。不需要记完整命令输出,记命令本身和判断逻辑就够了。这套笔记就是你面试时最有说服力的素材,比任何背诵都能体现你的实战深度。

# 示例:整理案例的一句话模板 # 现象:df -h 显示满,du 找不到大文件 → 命令:lsof | grep deleted → 解法:清空占用进程的fd

还有一个值得养成的习惯:每解决一个案例,就顺手把它转化成一个小脚本或者一个监控 item。比如我处理过一次“磁盘满导致服务写入失败”的故障后,就写了个检测脚本,在磁盘使用率超过 85% 时往告警群里发消息,同时列出排名前五的大文件路径,这让后续类似问题在变成故障前就被拦截了。实战能力的复利效应就是这么来的——一次踩坑,变成永久的防护能力。看完这些案例,希望你能找到自己的切入点,从最贴近你工作的那一类问题开始练手,逐步建立起属于你自己的实战方法论。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询