☰
Linux实战100例:从故障场景到命令肌肉记忆
2026/10/8 2:17:17 网站建设 项目流程

简介:这份Linux实战资源面向系统管理员、运维工程师及编程学习者,汇总了100个经典且具代表性的代码实例,内容覆盖网络调用命令、Apache参数配置详解、Linux错误代码解读,并针对应用过程中常见的诸多问题给出解决方法。资料包共204个文件,以195个HTML网页文档为主,便于浏览器直接查阅代码与说明,另含3个PDF手册和若干压缩包、Word文档,可辅助深入阅读或离线使用,整体压缩包约40.19MB,轻量便携。已有2180人学习下载,适合需要快速查询Linux命令用法、配置细节与排错思路的读者。资源尤其注重功能调用的完整过程说明,从基础指令到服务配置、错误定位均有涉及,可帮助学习者理解底层机制并应用到实际工作中,是一份注重实战与问题解决的高密度参考资料。

1. Linux实战100例:不是题目集,而是一份“报错→命令→确认”的肌肉记忆

深夜收到警报:磁盘使用率100%,服务全在报错。你手忙脚乱地搜“linux删除文件夹命令”,翻出一堆rm和find,却没有人告诉你先要定位大文件、再确认是不是被进程占住句柄。这种场景,恰恰是linux实战100例这类实战案例集想解决的:它不按命令字典排,而是按“一个事故场景 = 一个案例”来组织,让你在报错发生时,手比脑子先到。它能帮你建立从现象到命令的直线反射,适合准备面试的开发者、刚接手一批服务器的运维,以及做嵌入式linux项目却被构建、服务和日志折腾到半夜的人。刷一百遍手册,不如亲手把一百个场景各敲一遍。

2. 把“100例”拆成五个战场:分类、难度梯度与最小实验环境

2.1 案例分类:五条主线覆盖日常运维、故障定位与自动化

做100例之前,先得把这100个数落进几个筐里。不然很容易变成今天学ls明天学tar,学完就忘。我一般把案例按五个战场拆分:系统管理(用户、权限、服务)、文件与磁盘(查找、删除、挂载、扩容)、进程与服务(后台运行、信号、守护)、网络与安全(端口、连接、加固、审计)、脚本与自动化(Shell 封装、定时任务、日志分析)。

这五个战场不是官方的分类,而是从真实故障倒推出来的。你去看任何一份“linux某人常用命令大全运维”式的清单,最后能留下印象的,都是那些在事故里救过命的命令。与其背诵ps和kill的每个参数,不如把“进程僵死怎么办”编成一个案例,命令自然融入操作步骤。每一类配 20 个左右的案例,正好组成100例。

2.2 最小实验环境:用Linux镜像+虚拟机/云主机搭一个可反复重置的沙盒

做这100例,环境不能是生产服务器,你得有一个“拆不坏”的沙盒。常见做法是下载一个 linux镜像安装到虚拟机上,比如 Debian 或 Ubuntu Server;也可以直接开个按量计费的云主机,便宜且快。做安全审计方向的人,常把 Kali Linux 中文版安装在虚拟机里当靶机;做嵌入式linux项目的人,则用 QEMU 模拟一台 ARM 开发板,跑同一套系统就行。

装好系统后,第一件事是把 Python 环境备好,因为后续很多脚本和自动化案例要用到:

# Ubuntu/Debian 系安装 Python 3 与 pip sudo apt update sudo apt install -y python3 python3-pip python3-venv python3 --version pip3 --version

apt update先把软件源索引刷一遍,避免装到过期的包列表。安装时把python3-venv一并装上,是为了后面pip install时不破坏系统 Python 环境。注意:别用系统 Python 全局装一大堆包,否则环境变量一乱,你连python3指到哪都可能搞不清。

为什么不推荐只在 WSL 里练?WSL 的/proc、/sys和 systemd 行为与真实 Linux 服务器有差异,不少网络、时间同步和进程守护案例在 WSL 里会“翻车”,练到的是假经验。虚拟机或云主机的快照功能才是你的“后悔药”——案例演练前拍个快照,翻车后一键还原。

2.3 案例难度梯度:从单条命令到多命令协作,再到排障

100例要分难度阶梯,不然新手会卡死在第三题。我把难度分成四档:L1 是单条命令能完成的操作,比如新建用户、删除文件;L2 是组合拳,管道、重定向、通配符配合起来;L3 是脚本化,把参数、循环、判断写进 bash 文件;L4 是排障,给你一个坏掉的系统,你自己定位和恢复。以“删除文件夹”为例:

# L1:删除空目录 rmdir ./old # L2:删除非空目录并打印过程 rm -rv ./build/ # L3:脚本里先判断目录存在,再安全删除 [ -d "$BUILD_DIR" ] && rm -rf "$BUILD_DIR" # L4:发现脚本误删后,加入回收站 mv 保护 trash_dir=/root/.trash [ -d "$trash_dir" ] || mkdir -p "$trash_dir" mv "$BUILD_DIR" "$trash_dir/$(date +%Y%m%d_%H%M%S)"

注意 L3 里[ -d "$BUILD_DIR" ]这个判断很重要,它防止变量为空时变成rm -rf /。L4 的做法是把删除变成移动,给误删留出恢复窗口。我在整理案例集时,每个案例都会明确标出当前练习处于哪一档,建议 L3/L4 的案例反复练三遍以上,因为面试和故障现场考的就是这两档。

3. 重演五个最常翻车的高频案例:用户、文件、时间、后台与故障

3.1 新建用户并分配sudo提权:useradd/adduser与sudo的边界

用户管理是 linux系统管理 的入口,也是面试最爱问的细节。我见过不少人在useradd和adduser之间踩坑:在 CentOS 上用了adduser,结果发现它是useradd的软链接,配了一堆参数却报错。不同发行版行为不一样,所以必须掌握底层形态。

# 新建用户 alice,指定家目录和登录 shell sudo useradd -m -d /home/alice -s /bin/bash alice # 设置密码 sudo passwd alice # 把 alice 加入 sudo 组,获得提权能力 sudo usermod -aG sudo alice # 验证用户信息 id alice

useradd的-m参数是“没有家目录就自动创建”,不写的话/home/alice不会生成,很多新手会卡在“用户能建,但怎么没有 home”上。-s /bin/bash指定登录 shell,如果你写成了/usr/bin/nologin,这个用户就没法交互登录,只能跑服务。usermod -aG sudo alice是 linux提权 的标准姿势之一,-aG表示追加到 sudo 组,注意一定带-a,否则会把用户从其他组剔掉。改完还没生效?不用重启,重新登录即可。

更细的坑:如果你手工编辑/etc/sudoers给某人提权,语法写错会让所有 sudo 直接瘫痪。正确做法是用visudo命令来改,它会在保存前校验语法。被授权的用户第一次执行sudo时会提示输密码,如果提示“no tty present”,那就去检查/etc/sudoers里的requiretty设置,这也是运维场景里常见的坑。

3.2 删除文件夹:rm的边界、find删除与“后悔药”

“linux删除文件夹命令”大概是搜索量最高的词之一,但越是高频越容易翻车。rm -rf的效果立竿见影,可它的杀伤半径完全取决于你写的路径。生产环境我根本不直接配rm -rf,而是把它当成一个需要二次确认的操作。

# 删除空目录用 rmdir,删非空目录用 rm -rf rmdir ./empty_dir rm -rf ./build/ # 找出一周前的 .log 文件并删除 find /var/log -name "*.log" -type f -mtime +7 -delete # 更安全的“后悔药”:先 mv 到回收站 trash_dir=/root/.trash [ -d "$trash_dir" ] || mkdir -p "$trash_dir" mv "$PWD/$target_dir" "$trash_dir/$(date +%Y%m%d_%H%M%S)"

find -delete之前,我强烈建议先去掉-delete跑一遍,确认输出的文件列表没毛病。-mtime +7表示修改时间在7天以前,属于“老文件”,注意+7不包含第7天当天。至于“后悔药”,这招我是在真删过一批测试数据后总结的:mv到日期命名的目录后,观察几天确认没问题再清空,代价只是多占一点磁盘,挽回的可能是整晚加班。

3.3 查看系统时间与时间同步:timedatectl、chrony与NTP

排查问题的时候,第一眼先看时间。日志时间对不上,整个链路就变成黑匣子。很多人会用date看时间,却不知道怎么确认同步状态。这里要区分“系统时间”和“硬件时间”,也区分“时区错”和“同步失效”。

# 查看当前时间和时区,以及 NTP 同步状态 timedatectl # 开启自动时间同步 sudo timedatectl set-ntp true # 用 chrony 查看同步源和延迟 chronyc sources -v # 手动校时的兜底做法 sudo ntpdate -u cn.pool.ntp.org

timedatectl输出里重点看“Local time”和“System clock synchronized”。如果synchronized: no,说明 NTP 服务没跑。开启set-ntp true后,如果系统里装的是chrony,可以用chronyc sources -v看同步是否成功,标志是源前面出现^*。ntpdate是手动的硬拉时间,适合 NTP 服务还没起来时的应急,不要在服务运行中反复执行,否则会造成时间跳变。

时间同步问题在虚拟机里尤其玄学:宿主机休眠恢复后,客机时钟会漂移。解决方法是虚拟机设置里开启“客机时间同步”,并让宿主机的 chrony 也保持正常。服务器之间时间差超过几百毫秒,会话鉴权、日志排序都会乱,这也是排查“linux查看系统时间同步时间”这类需求时的直接切入点。

3.4 让后台运行指令不因界面退出而退出:nohup、setsid与systemd-run

这个需求在运维里几乎每周都会遇到:从终端启动一个长任务,关终端后任务就跟着死了。很多人第一反应是nohup,但nohup只解决SIGHUP,管不了会话终止和进程被拖累。完整的解法分四层:

# 方式一:nohup + &,临时后台 nohup ./long_task.sh > /tmp/long.log 2>&1 & # 方式二:先用 & 挂后台,再用 disown 脱离当前会话 ./long_task.sh & disown -h %1 # 方式三:setsid 直接开新会话 setsid ./long_task.sh </dev/null >/tmp/long.log 2>&1 & # 方式四:生产推荐 systemd-run,可管理、可查日志 systemd-run --unit=long_task --property=After=network.target \ --property=StandardOutput=append:/tmp/long.log ./long_task.sh

注意nohup后面最好同时重定向标准输出和错误输出,2>&1的位置不能乱写。disown -h %1里的%1对应jobs里的第一个任务,-h是挂起当前 shell 对它的 HUP 信号,避免它成为孤儿。setsid更彻底,直接让进程完全脱离原会话控制终端,关掉连接窗口它也不受影响。systemd-run是生产环境的最优解:它能生成一个 unit,用systemctl status查看状态,日志也统一进 journal 或指定文件。

我在本地验证过:用nohup启动一个 60 秒的 sleep,然后直接关闭 SSH 终端重进,进程还在;但如果是通过 nohup 启动的进程依赖父 shell 的某个环境变量,而那个变量只在登录 shell 里存在,进程起来就会报错。这种情况用systemd-run或setsid能避开,可它们不继承原 shell 的变量,所以脚本内不要依赖外部未导出的变量。

3.5 系统故障案例排查:磁盘满、CPU高、服务起不来的三板斧

“linux运维故障案例”和“linux系统故障案例”里,频率最高的是三种:磁盘满、CPU飙高、服务起不来。别急着一上来就重装,按顺序执行这三板斧:

# 第一板斧:看磁盘总量 df -h # 第二板斧:找目录内的大文件 du -sh /var /home /tmp 2>/dev/null find / -xdev -type f -size +500M -exec ls -lh {} \; 2>/dev/null | sort -k5 -h # 第三板斧:看 CPU 和内存 top -b -n 1 | head -20 ps -eo pid,ppid,pcpu,pmem,comm --sort=-pcpu | head # 服务起不来时,看状态和日志 systemctl status myservice journalctl -u myservice -n 50 --no-pager

注意df -h显示的Use%是 100%,但du统计出来的总量对不上,这种情况八成是:某个已删除的大文件仍被进程占用。用lsof | grep deleted能把这个进程找出来,重启它或 kill 它才能释放磁盘。find / -xdev中的-xdev表示不跨其他文件系统,防止它去扫/proc和挂载的存储目录,否则命令会卡死。top -b -n 1是批处理模式,适用于你连上去但交互界面刷新不出来的情况;sort -k5 -h按人在可读的大小排序,比纯看字节数直观。

服务起不来时,systemctl status只会告诉你“失败”的结论,真正的报错在journalctl里。多翻几十行日志,尤其是最后出现的ERROR或stack trace,定位速度比重启十次都快。

4. 用Shell把单点案例串成自动化:脚本、任务与进程间通信

4.1 把重复操作封装成脚本:一个日志清理脚本的完整迭代

案例单独做再多,最后都要落到能“一条命令自动跑”的脚本上。我以日志清理举例,展示从一个rm命令到完整脚本的迭代过程。

#!/bin/bash # 日志清理脚本:保留30天,超过7天的先压缩,超过30天的删除 set -eu LOG_DIR=${1:-/var/log/myapp} KEEP_DAYS=${2:-30} GZIP_AFTER_DAYS=${3:-7} [ -d "$LOG_DIR" ] || { echo "目录 $LOG_DIR 不存在" >&2; exit 1; } find "$LOG_DIR" -type f -name '*.log' -mtime +"$GZIP_AFTER_DAYS" -exec gzip {} \; find "$LOG_DIR" -type f -name '*.log.gz' -mtime +"$KEEP_DAYS" -delete echo "[$(date '+%F %T')] 清理完成:$LOG_DIR 保留 $KEEP_DAYS 天"

set -eu里-e是遇到任何非零退出码就中止,-u是使用未定义变量时报错。这一步直接避免了很多 shell 脚本“前半段正常,后半段因为变量空而误删”的悲剧。LOG_DIR=${1:-/var/log/myapp}是参数默认值写法,脚本不带参数也能安全运行。find先 gzip 早于 7 天的日志,再删除超过 30 天的.gz,顺序不能反过来,否则刚压缩的旧日志会被留到下一次才清。

然后用 cron 把它挂起来:

sudo crontab -e # 每天凌晨 2 点执行日志清理 0 2 * * * /opt/scripts/clean_log.sh /var/log/myapp 30 7 >> /var/log/clean_log_cron.log 2>&1

cron 环境不是登录 shell,PATH 可能很窄,所以脚本里凡是出现命令名,最好写绝对路径,或者在脚本开头显式export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin。输出的日志也要重定向到文件,否则 cron 把任务输出用邮件发给你,你在服务器上什么都看不到。

4.2 用systemd管理后台任务:比nohup更可靠的生产级方式

前面说过nohup只管 SIGHUP,不负责进程崩溃和开机启动。生产环境里,我会把长期运行的任务直接交给 systemd。它负责拉起、重启、日志聚合,比任何 “放后台” 的方式都省心。

sudo tee /etc/systemd/system/my-task.service > /dev/null <<'EOF' [Unit] Description=My background task After=network.target [Service] Type=simple User=ubuntu WorkingDirectory=/opt/myapp ExecStart=/opt/myapp/run.sh StandardOutput=append:/var/log/myapp/stdout.log StandardError=append:/var/log/myapp/stderr.log Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable --now my-task.service sudo systemctl status my-task.service

Type=simple表示ExecStart启动的进程就是主进程,适用于常驻前台程序。如果你的程序自己会 daemon 化(fork 到后台),那应该用Type=forking,否则 systemd 会认为主进程没起来而报错。Restart=on-failure是崩溃自动重启,RestartSec=5是等 5 秒再拉。StandardOutput=append:这种写法是把日志以追加方式交给 systemd 重定向,比启动时>/tmp/x.log更不容易丢。写完 unit 后必须daemon-reload,不然 systemd 不认新配置。

这条命令也验证了一个道理:与其背nohup的 20 种组合,不如把 systemd 这个 “更靠谱的后台” 学会,它能解决“linux让后台运行指令不因界面退出而退出”的更完整版本。

4.3 从脚本到进程间通信:命名管道、信号与共享文件

脚本之间需要协作时,就会碰到 linux进程间通信。四个基础手段里,优先级最高的是命名管道、信号和文件锁。代码先写三个小场景:

# 命名管道:一个进程写,另一个进程读 mkfifo /tmp/mycmd.fifo # 终端A cat /tmp/mycmd.fifo # 终端B echo "hello" > /tmp/mycmd.fifo # 信号:脚本捕获并执行自定义动作 trap 'echo "收到USR1,重载配置" >> /tmp/app.log' USR1 while true; do sleep 1; done # 发出信号 pkill -USR1 -f my_loop.sh # 共享文件做互斥锁 lockfile=/tmp/app.lock if mkdir "$lockfile" 2>/dev/null; then echo "获得锁" trap "rmdir $lockfile" EXIT else echo "已有实例在运行" >&2 exit 1 fi

命名管道的读写两端默认是阻塞的:没人读时echo会被卡住,这正好适合做简单的消息对传。信号里trap ... USR1让脚本能响应外部的重载请求,很多守护进程的“重载配置”就是这么实现的。文件锁用小命令mkdir的原子性来保证同一时刻只有一个实例能创建目录,比flock更易读,也比touch锁更可靠。

更复杂的进程间通信,可以再往 D-Bus、Unix socket 上走,但六成的运维场景用这三个基础方案就够了。嵌入式linux项目里,一个应用与另一个守护进程交换状态,也常绕不开这几个机制:要么写/tmp下的 socket,要么用信号触发重读配置。

5. 避坑:100例里最常翻车的5个现场与恢复习惯

这些坑我在做案例演练时全踩过,每一条都按“现象→原因→解决”写,直接照单自查。

5.1 现象:rm -rf 把整个根目录删了

原因:脚本里写了rm -rf "$DIR/",但$DIR被赋值为空字符串,命令展开后变成rm -rf /。更隐蔽的是路径拼接错误,$DIR末尾带/又跟了..,就删到了上层目录。

解决:脚本开头写set -u,让未定义变量直接报错;删除前用[ -n "$DIR" ]确认路径非空;重要路径使用mv到回收站,而不是直接rm。生产服务器操作大目录前,先df -h和du -sh确认目标是什么,再动刀。

5.2 现象:sudo 执行时报 “syntax error near unexpected token”,所有 sudo 都失效

原因:有人直接vim /etc/sudoers且写错了语法,保存后 sudo 无法解析 sudoers 文件,导致提权通道全部堵死。

解决:永远只用visudo编辑 sudoers,它会在保存前执行语法检查。如果已经改坏了,用pkexec visudo绕过 sudo 直接调用 pkexec 修复,或者用另一台有 root 的主机挂载修复;要是单机就重启进单用户模式。权限类操作最好先备份/etc/sudoers,这是我养成的条件反射。

5.3 现象:服务器时间总是差8小时,timedatectl显示 NTP inactive

原因:时区还是 UTC,或者 chrony 没装、没启动;虚拟机里更常见的是宿主机休眠导致客机时钟漂移,NTP 同步却因为防火墙丢了 123/UDP 端口。

解决:timedatectl set-timezone Asia/Shanghai改时区,timedatectl set-ntp true开启同步;装 chrony 后用chronyc sources -v看有没有^*状态的同步源。虚拟机设置里把“客机时间同步”打开,宿主机的时间同步本身也要正常。用ntpdate应急可以,但别在 chrony 运行时混用。

5.4 现象:nohup 起的后台任务,终端关了还在,第二天却没了

原因:nohup 只屏蔽了终端关闭的 SIGHUP,但进程本身因为段错误被系统杀掉,或者被 systemd 判定 OOM 杀掉,又或者日志文件被 logrotate 改名,进程继续往旧文件句柄写没意义的内容,观察时误以为它“没了”。

解决:生产环境不要只靠 nohup。把它写成 systemd service,用Restart=on-failure自动拉起,用journalctl查崩溃日志。如果一定要用 nohup,至少把stdout和stderr都重定向,并确认脚本在独立目录下运行,避免当前目录被清理。

5.5 现象:linux系统安装python后用 pip 装包,报 “externally-managed-environment”

原因:Ubuntu 23.04 之后的系统 Python 启用了外部环境管理保护,不允许系统解释器直接被 pip 写全局包。

解决:用python3 -m venv ~/myenv建虚拟环境,激活之后再pip install;部署新服务直接把依赖装进 Docker 镜像或独立 conda 环境。临时测试可以pip3 install --break-system-packages,但这不是长期去处,系统一升级就会出问题。

6. 把100例变成肌肉记忆:验证清单与复盘习惯

案例练过不等于掌握,真正掌握是“下次故障发生时,不用翻命令就能恢复”。我给自己设计了一个验证清单,核心是把每个案例压缩成“需求、命令、预期输出”三个要素,然后让脚本自动检查。

check_case() { case_name=$1 command=$2 expect=$3 output=$(eval "$command" 2>/dev/null) if echo "$output" | grep -q "$expect"; then echo "[OK] $case_name" else echo "[FAIL] $case_name 实际:$output" fi } check_case "磁盘根分区可用" "df -h / | tail -1" "/dev/.*" check_case "用户列表包含alice" "grep alice /etc/passwd" "alice"

建议每周抽 10 个案例跑一遍,只保留[OK]越来越多的成就感,[FAIL]的立即回炉。遇到新故障,我的复盘模板是:记录现场现象、写出当时执行的命令、在沙盒里把最小复现步骤重演一遍、最后把解决办法补进自己的案例集。这样积累出来的不是 100 个命令,而是 100 段“报错→命令→确认”的肌肉记忆。

把最危险的一条命令先封装成回收站函数,把最难缠的一次排障重演成最小案例,是我这几年养成的习惯了,希望帮到你。

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

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

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

立即咨询