Linux 命令全家桶:28 章 200+ 命令实战速查(附面试考点 · 踩坑指南 · 发行版对照)
这是一份能直接照着敲 的 Linux 命令实战手册:28 章、200+ 命令、100+ 代码示例 。从入门(文件 / 目录 / 权限)到进阶(文本三剑客、进程网络、防火墙 SSH),再到文件系统原理、网络抓包、面试考点、踩坑锦集、发行版对照------日常开发、运维排障、求职面试一册搞定。
适合人群:Linux 初学者 / 后端与运维工程师 / 备战面试的同学读完你将获得:
- 200+ 常用命令的直接复用手册,附 30 条速查表
- 16 个高频面试考点速答,直接背答案
- 12 个新手易踩的坑与正确姿势,少走弯路
- 五大发行版(Debian / RHEL / Arch / SUSE)命令对照与迁移指南
阶段 内容定位 你将学会 命令入门 终端、帮助与路径 命令格式、man / help、绝对与相对路径 文件与目录 日常增删改查 ls / cd / cp / mv / rm / mkdir / touch 等 内容查看与搜索 读取与定位 cat / head / tail / less / find / grep 文本三剑客 行级处理神器 grep / sed / awk 组合使用 权限与用户 多人协作基石 chmod / chown / useradd / sudo 进程与系统 运行态管理 ps / top / kill / systemctl / 定时任务 网络与磁盘 连通、安全与容量 ping / curl / 防火墙 / SSH / 日志 / df / du / 压缩归档 包管理 软件安装升级 apt / yum / dnf / 源码编译 实战场景 综合演练 日志排查 / 批量处理 / 脚本化 原理与进阶 存储/网络/面试/避坑 inode 文件系统、tcpdump 抓包、发行版对照、面试考点
先看一张全章知识脑图,心里有张地图再上路(点击图片可查看高清大图):

目录
命令入门
- [一、Linux 命令基础:打开终端的第一步](#一、Linux 命令基础:打开终端的第一步)
- 二、目录与路径:理解文件系统结构
文件与目录操作
文本处理
权限与用户
- 九、用户与组管理
- [十、文件权限:rwx 与 chmod / chown](#十、文件权限:rwx 与 chmod / chown)
进程与系统
- 十一、进程管理与后台运行
- [十二、系统服务:systemctl 管理](#十二、系统服务:systemctl 管理)
- [十三、定时任务:cron 与 at](#十三、定时任务:cron 与 at)
网络、安全与系统
- 十四、网络诊断与请求
- [十五、防火墙命令:ufw / firewalld / iptables](#十五、防火墙命令:ufw / firewalld / iptables)
- [十六、SSH 远程连接与文件传输](#十六、SSH 远程连接与文件传输)
- [十七、日志查看:journalctl 与系统日志](#十七、日志查看:journalctl 与系统日志)
- 十八、磁盘与内存监控
- [十九、压缩打包:tar 与 zip](#十九、压缩打包:tar 与 zip)
软件与综合
- [二十、软件包管理:apt / yum / dnf](#二十、软件包管理:apt / yum / dnf)
- [二十一、Shell 常用技巧与快捷键](#二十一、Shell 常用技巧与快捷键)
- 二十二、高频实战场景演练
- 二十三、总结与速查表
原理进阶与面试避坑
- [二十四、文件系统与 inode:理解 Linux 如何存储文件](#二十四、文件系统与 inode:理解 Linux 如何存储文件)
- [二十五、网络抓包与连接排查:tcpdump / ss / lsof / ip](#二十五、网络抓包与连接排查:tcpdump / ss / lsof / ip)
- 二十六、高频面试考点速答
- [二十七、踩坑锦集:新手最容易犯的 12 个错误](#二十七、踩坑锦集:新手最容易犯的 12 个错误)
- 二十八、发行版差异与命令对照表
一、Linux 命令基础:打开终端的第一步
1.1 命令的基本格式
Linux 命令的统一格式是:
bash
命令名 [选项] [参数]
- 命令名 :要执行的程序,如
ls、cd、cat; - 选项 :修饰命令行为,短选项用单个
-(如-l),长选项用--(如--help),多个短选项可以合并(如-la); - 参数:命令操作的对象,通常是文件、目录或字符串。
来看几个真实例子:
bash
# 列出当前目录所有文件(含隐藏文件),并显示详细信息
ls -la
# 递归删除非空目录(后面会细讲,谨慎使用!)
rm -rf mydir
# 长选项写法
ls --all --long
1.2 获取帮助:命令不会用怎么办?
Linux 内置三套"说明书",按详细程度排列:
bash
# 1. 查看命令手册(最详细,q 退出)
man ls
# 2. 查看命令的简要帮助
ls --help
# 3. 查看 Shell 内置命令帮助(cd、echo 等属于内置命令)
help cd
实战技巧 :忘了某个功能该用哪个命令,可以用 apropos 按关键词搜索:
bash
# 搜索与"复制"相关的所有命令
apropos copy
# 搜索与"压缩"相关的命令
apropos compress
1.3 命令的执行:前一个输出作为后一个输入
Linux 命令可以像管道一样串联,用 | 把前一个命令的输出"喂"给下一个命令:
bash
# 查看进程列表,再过滤出 nginx 相关进程
ps aux | grep nginx
# 查看磁盘占用,只看前 5 行
df -h | head -5
# 统计当前目录下文件个数
ls | wc -l
记忆口诀 :管道 | 就像水管的接头,把左边命令"流出来的水"接给右边命令处理。
二、目录与路径:理解文件系统结构
先看 Linux 目录结构全景(重点记住 /、/etc、/home、/var、/tmp 五个):
#mermaid-svg-w7s5v537fkUhOfv7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-w7s5v537fkUhOfv7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-w7s5v537fkUhOfv7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-w7s5v537fkUhOfv7 .error-icon{fill:#552222;}#mermaid-svg-w7s5v537fkUhOfv7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-w7s5v537fkUhOfv7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-w7s5v537fkUhOfv7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-w7s5v537fkUhOfv7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-w7s5v537fkUhOfv7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-w7s5v537fkUhOfv7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-w7s5v537fkUhOfv7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-w7s5v537fkUhOfv7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-w7s5v537fkUhOfv7 .marker.cross{stroke:#333333;}#mermaid-svg-w7s5v537fkUhOfv7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-w7s5v537fkUhOfv7 p{margin:0;}#mermaid-svg-w7s5v537fkUhOfv7 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-w7s5v537fkUhOfv7 .cluster-label text{fill:#333;}#mermaid-svg-w7s5v537fkUhOfv7 .cluster-label span{color:#333;}#mermaid-svg-w7s5v537fkUhOfv7 .cluster-label span p{background-color:transparent;}#mermaid-svg-w7s5v537fkUhOfv7 .label text,#mermaid-svg-w7s5v537fkUhOfv7 span{fill:#333;color:#333;}#mermaid-svg-w7s5v537fkUhOfv7 .node rect,#mermaid-svg-w7s5v537fkUhOfv7 .node circle,#mermaid-svg-w7s5v537fkUhOfv7 .node ellipse,#mermaid-svg-w7s5v537fkUhOfv7 .node polygon,#mermaid-svg-w7s5v537fkUhOfv7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-w7s5v537fkUhOfv7 .rough-node .label text,#mermaid-svg-w7s5v537fkUhOfv7 .node .label text,#mermaid-svg-w7s5v537fkUhOfv7 .image-shape .label,#mermaid-svg-w7s5v537fkUhOfv7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-w7s5v537fkUhOfv7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-w7s5v537fkUhOfv7 .rough-node .label,#mermaid-svg-w7s5v537fkUhOfv7 .node .label,#mermaid-svg-w7s5v537fkUhOfv7 .image-shape .label,#mermaid-svg-w7s5v537fkUhOfv7 .icon-shape .label{text-align:center;}#mermaid-svg-w7s5v537fkUhOfv7 .node.clickable{cursor:pointer;}#mermaid-svg-w7s5v537fkUhOfv7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-w7s5v537fkUhOfv7 .arrowheadPath{fill:#333333;}#mermaid-svg-w7s5v537fkUhOfv7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-w7s5v537fkUhOfv7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-w7s5v537fkUhOfv7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-w7s5v537fkUhOfv7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-w7s5v537fkUhOfv7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-w7s5v537fkUhOfv7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-w7s5v537fkUhOfv7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-w7s5v537fkUhOfv7 .cluster text{fill:#333;}#mermaid-svg-w7s5v537fkUhOfv7 .cluster span{color:#333;}#mermaid-svg-w7s5v537fkUhOfv7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-w7s5v537fkUhOfv7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-w7s5v537fkUhOfv7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-w7s5v537fkUhOfv7 .icon-shape,#mermaid-svg-w7s5v537fkUhOfv7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-w7s5v537fkUhOfv7 .icon-shape p,#mermaid-svg-w7s5v537fkUhOfv7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-w7s5v537fkUhOfv7 .icon-shape .label rect,#mermaid-svg-w7s5v537fkUhOfv7 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-w7s5v537fkUhOfv7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-w7s5v537fkUhOfv7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-w7s5v537fkUhOfv7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} /
bin 基本命令
etc 系统配置
home 用户家目录
root 管理员家目录
var 日志缓存等动态数据
tmp 临时文件
usr 软件资源
dev 设备文件
proc 内核与进程信息
2.1 Linux 目录结构速览
Linux 一切皆文件,目录结构是倒挂的树,根目录是 /:
| 目录 | 作用 |
|---|---|
/ |
根目录,整个文件系统的起点 |
/home |
普通用户的家目录(如 /home/zhangsan) |
/root |
root 用户的家目录 |
/etc |
系统配置文件(网络、服务、软件配置都在这里) |
/var |
经常变化的数据:日志(/var/log)、缓存 |
/usr |
系统软件安装目录(类似 Windows 的 Program Files) |
/opt |
第三方软件安装目录 |
/tmp |
临时文件目录,重启后通常被清空 |
/bin、/sbin |
系统命令存放处 |
/dev |
设备文件(磁盘、终端等) |
/proc |
运行中的进程和内核信息(虚拟目录) |
2.2 绝对路径与相对路径
- 绝对路径 :从根
/开始写,如/home/zhangsan/test.txt,任何时候都能直接定位; - 相对路径 :从当前位置开始写,如
./test.txt(当前目录下)、../test.txt(上一级目录下)。
bash
# 特殊符号
. # 当前目录
.. # 上一级目录
~ # 当前用户的家目录(root 用户就是 /root)
- # 上一次所在目录(cd - 可以来回切换)
# 回到家目录
cd ~
# 回到上一次的目录
cd -
# 查看当前位置(打印工作目录)
pwd
2.3 快速跳转:cd 的几种姿势
bash
# 直接进入指定目录
cd /var/log
# 一次跳多级
cd /home/zhangsan/projects/blog
# 返回上一级
cd ..
# 回到家目录
cd
# 进入某用户的家目录
cd ~lisi
知识点回顾 :
pwd随时确认自己在哪,防止命令敲错目录。初学者 80% 的误操作都来自"不知道当前在哪"。
三、文件与目录的增删改查
3.1 查看:ls(list,列出)
ls 是最常用的命令,没有之一:
bash
# 列出当前目录
ls
# 列出详细信息(权限、属主、大小、时间)
ls -l
# 显示所有文件(含以 . 开头的隐藏文件)
ls -a
# 常用组合
ls -la # 详细信息 + 隐藏文件
ls -lh # 人类可读的大小(KB/MB/GB)
ls -lt # 按修改时间排序(新的在前)
ls -lS # 按文件大小排序
ls -R # 递归列出子目录内容
ls *.txt # 通配符:只看 txt 文件
3.2 创建:mkdir 与 touch
bash
# 创建目录
mkdir mydir
# 创建多级目录(-p 自动创建缺失的父目录)
mkdir -p a/b/c/d
# 同时创建多个目录
mkdir dir1 dir2 dir3
# 创建空文件
touch file.txt
# 批量创建文件
touch a.txt b.txt c.txt
3.3 复制:cp(copy)
bash
# 复制文件到指定目录
cp file.txt /home/zhangsan/backup/
# 复制并改名
cp file.txt file_copy.txt
# 复制目录(-r 递归)
cp -r mydir /backup/
# 保留文件属性(权限、时间戳)复制
cp -p file.txt file_p.txt
# 常用组合:递归 + 保留属性 + 覆盖前询问
cp -rp dir1 dir2
# 强制覆盖(不询问)
cp -f a.txt b.txt
3.4 移动与重命名:mv(move)
mv 既能移动,也能重命名,是同一个命令:
bash
# 重命名文件
mv oldname.txt newname.txt
# 移动文件到其他目录
mv file.txt /tmp/
# 移动并改名
mv file.txt /tmp/file2.txt
# 移动整个目录
mv mydir /home/zhangsan/archive/
注意 :mv 在同一文件系统内是"改名字",速度极快;跨磁盘(如从 / 移动到 /home 挂载的其他盘)才会真正复制。
3.5 删除:rm(remove)------危险操作
bash
# 删除文件(会询问确认)
rm file.txt
# 强制删除(不询问)
rm -f file.txt
# 删除空目录
rmdir emptydir
# 递归删除目录及其内容(-r),强制不询问(-f)
rm -rf mydir
安全提醒 :
rm -rf /会删除根目录,直接把系统"删除"了!日常建议:
- 删除前先
ls确认目录内容;- 重要文件先备份或用
mv移到回收目录;- 可以用
alias rm='rm -i'让删除前总是确认(写入~/.bashrc生效)。
3.6 其他高频操作
bash
# 创建硬链接(同一文件的另一个名字,共享内容)
ln file.txt file_hard.txt
# 创建软链接(类似 Windows 快捷方式)
ln -s /usr/bin/python3 /usr/local/bin/python
# 查看文件类型
file app.py
# 输出:app.py: Python script, ASCII text executable
# 清空屏幕
clear
# 查看命令在哪个位置
which python3
# 输出:/usr/bin/python3
四、文件内容查看与统计
4.1 直接查看:cat / tac / nl
bash
# 查看整个文件(一次性输出全部内容)
cat /etc/passwd
# 倒序输出(tac 就是 cat 反过来)
tac /etc/passwd
# 带行号输出
nl /etc/passwd
# 将多个文件拼接输出
cat a.txt b.txt
4.2 分页查看:less / more
文件太长时,cat 会刷屏,此时用分页器:
bash
# 分页查看(推荐 less,支持上下翻页和搜索)
less /var/log/syslog
# 在 less 中的常用按键
# 空格/PageDown:下一页 b/PageUp:上一页
# /关键词:向下搜索 ?关键词:向上搜索
# n:下一个匹配 N:上一个匹配
# q:退出
4.3 头尾查看:head / tail
bash
# 查看前 10 行(默认)
head /etc/passwd
# 查看前 20 行
head -20 /etc/passwd
# 查看最后 10 行(默认)
tail /etc/passwd
# 实时跟踪文件新增内容(-f 跟随),调试日志神器!
tail -f /var/log/nginx/access.log
# 实时跟踪并带行号
tail -f -n 50 /var/log/app.log
经典场景 :排查线上问题时,一边刷新页面一边 tail -f 看日志,新请求立刻打印出来。
4.4 统计与排序:wc / sort / uniq
bash
# 统计行数、单词数、字节数
wc -l /etc/passwd # 行数
wc -w file.txt # 单词数
wc -c file.txt # 字节数
# 排序(默认按字典序)
sort file.txt
# 按数字排序
sort -n scores.txt
# 倒序排序
sort -r file.txt
# 去重(必须先排序才能正确去重)
sort file.txt | uniq
# 统计每行出现次数并按次数排序
sort file.txt | uniq -c | sort -rn
# 实战:统计访问日志中 IP 的访问次数 Top 10
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
五、查找文件与定位命令
5.1 find:按条件查找(功能最强)
bash
# 按文件名查找(当前目录递归)
find . -name "*.log"
# 全盘查找某个文件
find / -name "nginx.conf" 2>/dev/null
# 按目录查找
find /home -type d -name "project*"
# 按文件类型查找(f 普通文件,d 目录,l 软链接)
find /var -type f -name "*.log"
# 按大小查找(大于 100M 的文件)
find / -size +100M
# 按修改时间查找(7 天内修改过的文件)
find /home -mtime -7
# 查找并执行操作(把找到的日志文件删除)
find /tmp -name "*.tmp" -exec rm -f {} \;
# 查找并批量复制
find . -name "*.jpg" -exec cp {} /backup/ \;
-exec ... {} \;的格式是固定的:{}代表"找到的每个文件",\;表示命令结束。
5.2 locate:按数据库快速查找
bash
# 先更新数据库(新文件需要先更新才能被找到)
sudo updatedb
# 按名字模糊查找(比 find 快很多)
locate nginx.conf
5.3 which / whereis:定位命令
bash
# 命令在哪个目录
which python3
# 命令及其手册、源码位置
whereis python3
# 查找命令的详细信息
type ls
# 输出:ls is aliased to `ls --color=auto'
六、grep:文本搜索第一利器
6.1 基本用法
grep 从文件或输入流中按模式匹配并打印匹配行:
bash
# 在文件中搜索关键词
grep "error" /var/log/syslog
# 在多个文件中搜索
grep "error" /var/log/*.log
# 从管道输入中过滤
ps aux | grep nginx
# 忽略大小写
grep -i "error" file.txt
# 显示行号
grep -n "error" file.txt
# 递归搜索目录下所有文件
grep -r "TODO" /home/zhangsan/projects/
# 只显示文件名(不显示匹配内容)
grep -l "error" /var/log/*.log
# 反向匹配(不含该关键词的行)
grep -v "debug" app.log
# 统计匹配行数
grep -c "error" app.log
6.2 正则表达式实战
bash
# 以 error 开头的行(^ 表示行首)
grep "^error" app.log
# 以 .log 结尾的($ 表示行尾)
grep "\.log$" files.txt
# 匹配 2026 年 8 月任意日期
grep "2026-08-1[0-9]" app.log
# 匹配 ip 或 IP
grep -E "ip|IP" app.log
# 匹配 3~5 位数字
grep -E "[0-9]{3,5}" app.log
grep -E启用扩展正则,支持|、{}、+、?等语法,写复杂规则时必加。
6.3 常用组合套路
bash
# 统计错误出现次数
grep -c "ERROR" app.log
# 搜索但排除日志文件
grep -r "password" --exclude="*.log" /etc/
# 只搜 .py 和 .js 文件
grep -r "TODO" --include="*.py" --include="*.js" /home/zhangsan/
# 匹配结果高亮显示(-E 正则 + --color)
grep --color -E "WARN|ERROR" app.log
# 取匹配行的前 3 行、后 3 行上下文
grep -B 3 -A 3 "Exception" app.log
七、sed:流式文本编辑器
7.1 sed 是什么?
sed(Stream Editor,流编辑器)逐行读取文本、按规则处理后输出,不改原文件 (除非加 -i)。格式:
bash
sed [选项] '地址 操作' 文件
7.2 替换:s 命令(最常用)
bash
# 把每行第一个 error 替换为 ERROR(只改输出,不改文件)
sed 's/error/ERROR/' app.log
# 全局替换(行内所有匹配,g 表示 global)
sed 's/error/ERROR/g' app.log
# 指定行号替换
sed '3s/error/ERROR/' app.log
# 指定行范围替换
sed '5,10s/error/ERROR/g' app.log
# 正则替换:把 2026 年改成 2027 年
sed 's/2026/2027/g' dates.txt
# 真正写回文件(-i 慎用,建议先备份)
sed -i.bak 's/old/new/g' config.conf
7.3 删除与打印
bash
# 删除第 3 行
sed '3d' file.txt
# 删除 5~10 行
sed '5,10d' file.txt
# 删除包含 error 的行
sed '/error/d' app.log
# 只打印 1~5 行(-n 抑制默认输出 + p 打印)
sed -n '1,5p' /etc/passwd
# 只打印含 root 的行
sed -n '/root/p' /etc/passwd
7.4 插入与追加
bash
# 在第 2 行前插入一行
sed '2i INSERTED LINE' file.txt
# 在第 2 行后追加一行
sed '2a APPENDED LINE' file.txt
# 在文件末尾追加
sed '$a THE END' file.txt
经典实战 :批量把配置文件的 # 注释取消掉:
bash
# 把所有以 # 开头的行删除(等价于"取消注释")
sed '/^#/d' nginx.conf
# 把 nginx 配置中的 server_name 全部替换
sed -i 's/server_name .*;/server_name www.example.com;/' nginx.conf
八、awk:列处理与统计神器
8.1 基础:按列取数
awk 按分隔符把每行拆成多个"字段",$1 第一列、$2 第二列......$0 整行,默认分隔符是空格/制表符:
bash
# 打印每行的第 1 列和第 3 列
awk '{print $1, $3}' /etc/passwd
# 指定分隔符为冒号(-F 指定)
awk -F: '{print $1, $7}' /etc/passwd
# 打印整行
awk '{print $0}' file.txt
# 打印行号和内容
awk '{print NR, $0}' file.txt
实战:查看所有用户名及其登录 shell:
bash
awk -F: '{print $1 " 的登录 shell 是 " $7}' /etc/passwd
8.2 内置变量
| 变量 | 含义 |
|---|---|
NR |
当前处理的行号 |
NF |
当前行的字段个数 |
$0 |
整行内容 |
$1~$n |
第 n 个字段 |
FS |
字段分隔符(等价于 -F) |
bash
# 打印每行行号和字段总数
awk '{print "第" NR "行,共" NF "列"}' file.txt
# 打印每行最后一个字段
awk '{print $NF}' file.txt
8.3 条件过滤
bash
# 只处理第 3 列大于 100 的行
awk '$3 > 100 {print $1, $3}' scores.txt
# 只处理包含 error 的行
awk '/error/ {print NR": "$0}' app.log
# 行号在 10~20 之间的行
awk 'NR>=10 && NR<=20 {print $0}' file.txt
# 组合条件:第 1 列是 root 或者 uid 大于 1000
awk -F: '$1=="root" || $3>1000 {print $1, $3}' /etc/passwd
8.4 统计与求和
bash
# 统计文件行数(等价 wc -l)
awk 'END {print NR}' file.txt
# 求第 2 列的和
awk '{sum += $2} END {print "总和:", sum}' sales.txt
# 求平均值
awk '{sum += $2; count++} END {print "平均值:", sum/count}' sales.txt
# 统计各 IP 访问次数(等价前面 sort+uniq 组合)
awk '{count[$1]++} END {for (ip in count) print ip, count[ip]}' access.log
知识点回顾 :
END { ... }表示读完所有行之后执行一次,是统计类任务的固定套路。
8.5 三剑客组合实战
bash
# 找出日志中 500 错误的 IP,去重计数
grep " 500 " access.log | awk '{print $1}' | sort | uniq -c | sort -rn
# 把配置文件中的 server_name 全部打印
awk '/server_name/ {print $2}' nginx.conf | sed 's/;//'
# 统计 CPU 占用最高的 5 个进程(ps 输出第 3 列是 CPU%)
ps aux | awk '{print $3, $11}' | sort -rn | head -5
九、用户与组管理
9.1 用户管理
bash
# 创建用户(-m 创建家目录,-s 指定 shell)
sudo useradd -m -s /bin/bash zhangsan
# 设置或修改密码
sudo passwd zhangsan
# 查看用户信息
id zhangsan
# 修改用户(把 zhangsan 加入 sudo 组,-aG 追加)
sudo usermod -aG sudo zhangsan
# 锁定用户(禁止登录)
sudo usermod -L zhangsan
# 解锁用户
sudo usermod -U zhangsan
# 删除用户(-r 连同家目录一起删)
sudo userdel -r zhangsan
9.2 用户相关文件
bash
# 查看所有用户(每行一个:用户名:x:uid:gid:描述:家目录:shell)
cat /etc/passwd
# 查看用户密码影子文件(存放加密后的密码)
cat /etc/shadow
# 查看所有组
cat /etc/group
9.3 切换用户与提权
bash
# 切换到 root(输入 root 密码)
su -
# 以 root 身份执行单条命令(输入当前用户密码)
sudo systemctl restart nginx
# 查看当前用户
whoami
# 查看当前用户身份详情
id
sudo 与 su 的区别:
| 命令 | 用法 | 密码 | 场景 |
|---|---|---|---|
su |
切换用户身份 | 目标用户密码 | 长时间以 root 工作 |
sudo |
以 root 执行单条命令 | 当前用户密码 | 偶发提权,更安全 |
十、文件权限:rwx 与 chmod / chown
10.1 权限三要素
bash
ls -l script.sh
# -rwxr-xr-- 1 root root 1234 Aug 17 10:00 script.sh
权限字符串共 10 位:
- rwx r-x r--
│ │ │ └── 其他用户权限
│ │ └─────── 所属组权限
│ └──────────── 属主权限
└──────────────── 文件类型(- 普通文件,d 目录,l 软链接)
| 字符 | 含义 | 对文件 | 对目录 |
|---|---|---|---|
r (4) |
读 | 查看内容 | 列出目录内容 |
w (2) |
写 | 修改内容 | 增删目录中的文件 |
x (1) |
执行 | 运行程序 | 进入目录(cd) |
10.2 chmod:修改权限
数字法(最常用):r=4, w=2, x=1,三者相加:
bash
# 权限数字:7=rwx, 6=rw-, 5=r-x, 4=r--, 0=---
# 属主读写执行,组读写,其他只读
chmod 764 script.sh
# 属主全部权限,组和其他只读执行
chmod 755 script.sh
# 只读(四类人都只读)
chmod 444 file.txt
# 给所有用户(a=all)加执行权限
chmod +x script.sh
# 去掉其他用户的写权限
chmod o-w file.txt
# 递归修改目录下所有文件
chmod -R 755 /home/zhangsan/www/
符号法:u 属主、g 组、o 其他、a 所有人;+ 加、- 减、= 设定。
10.3 chown:修改属主与属组
bash
# 修改文件属主
sudo chown zhangsan file.txt
# 同时修改属主和属组
sudo chown zhangsan:devteam file.txt
# 只修改属组
sudo chown :devteam file.txt
# 递归修改目录
sudo chown -R zhangsan:devteam /home/zhangsan/project/
10.4 实战场景
bash
# 部署网站后统一权限:目录 755、文件 644
sudo find /var/www -type d -exec chmod 755 {} \;
sudo find /var/www -type f -exec chmod 644 {} \;
# 给脚本执行权限并运行
chmod +x deploy.sh && ./deploy.sh
十一、进程管理与后台运行
11.1 查看进程:ps / top
bash
# 查看当前终端进程
ps
# 查看所有进程(详细格式,最常用)
ps aux
# 只看指定进程(配合 grep 过滤)
ps aux | grep nginx
# 树状显示进程关系
pstree
# 动态监控(类似 Windows 任务管理器,q 退出)
top
# 更友好的动态监控(htop 需安装)
htop
# 只看某个用户的进程
ps -u zhangsan
ps aux 各列含义:USER 属主、PID 进程号、%CPU CPU 占用、%MEM 内存占用、STAT 状态(S 睡眠、R 运行、Z 僵尸)、COMMAND 命令。
11.2 终止进程:kill
bash
# 温柔地请求进程退出(默认 SIGTERM,15)
kill 1234
# 强制杀死(SIGKILL,9,慎用)
kill -9 1234
# 按名字批量杀掉
pkill nginx
# 杀掉某个用户的所有进程
pkill -u zhangsan
# 优雅停止(等待进程清理资源)
kill -15 1234
教训 :
kill -9是最后手段。先试kill(SIGTERM),进程会保存数据、释放资源;-9直接砍断,可能导致数据丢失。
11.3 后台运行
bash
# 命令后面加 & 放入后台
python3 app.py &
# 查看后台任务
jobs
# 把后台任务调到前台
fg %1
# 把暂停的任务恢复后台运行
bg %1
# 后台运行并完全脱离终端(关闭终端也不死)
nohup python3 app.py > app.log 2>&1 &
# 分析这条经典命令:
# nohup :忽略挂断信号,终端关闭进程继续
# > app.log :标准输出写入日志文件
# 2>&1 :错误输出也写入同一个文件
# & :放入后台
实用场景 :服务器上跑长任务(训练模型、同步数据),用 nohup 后即使断开 SSH 也不会中断:
bash
nohup python3 train.py > train.log 2>&1 &
tail -f train.log # 另一个终端实时看进度
11.4 端口与占用
bash
# 查看端口监听情况
ss -tlnp
# 查看 80 端口被谁占用
lsof -i :80
# 查看 8080 端口占用并杀掉进程
lsof -i :8080
kill -9 $(lsof -t -i :8080)
十二、系统服务:systemctl 管理
12.1 systemctl 基本操作
现代 Linux(CentOS 7+、Ubuntu 16.04+)用 systemd 管理服务,核心命令是 systemctl:
bash
# 启动服务
sudo systemctl start nginx
# 停止服务
sudo systemctl stop nginx
# 重启服务
sudo systemctl restart nginx
# 重新加载配置(不中断服务,改配置后推荐)
sudo systemctl reload nginx
# 查看服务状态
sudo systemctl status nginx
# 开机自启
sudo systemctl enable nginx
# 取消开机自启
sudo systemctl disable nginx
# 启用并立即启动
sudo systemctl enable --now nginx
12.2 服务状态查询
bash
# 列出所有运行中的服务
systemctl list-units --type=service --state=running
# 列出所有开机自启的服务
systemctl list-unit-files | grep enabled
# 查看服务是否在运行
systemctl is-active nginx
# 查看服务是否开机自启
systemctl is-enabled nginx
12.3 自定义服务(示例:写一个自己的服务)
新建 /etc/systemd/system/myapp.service:
ini
[Unit]
Description=My Python App
After=network.target
[Service]
ExecStart=/usr/bin/python3 /opt/myapp/app.py
Restart=always
User=zhangsan
[Install]
WantedBy=multi-user.target
然后:
bash
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启动并设置开机自启
sudo systemctl enable --now myapp
# 查看日志(journalctl 查看服务日志,详见第十七章)
journalctl -u myapp -f
十三、定时任务:cron 与 at
13.1 crontab:周期性任务
bash
# 编辑当前用户的定时任务(首次会提示选择编辑器)
crontab -e
# 列出当前用户的定时任务
crontab -l
# 删除所有定时任务
crontab -r
cron 表达式格式:分 时 日 月 星期 命令
bash
# 每分钟执行
* * * * * /opt/scripts/check.sh
# 每天凌晨 2 点执行
0 2 * * * /opt/scripts/backup.sh
# 每周一早上 9 点执行
0 9 * * 1 /opt/scripts/report.sh
# 每月 1 号执行
0 0 1 * * /opt/scripts/clean.sh
# 每小时的第 15 分钟执行
15 * * * * /opt/scripts/task.sh
# 每 5 分钟执行
*/5 * * * * /opt/scripts/ping.sh
# 每天的 8 点到 18 点,每 2 小时执行
0 8-18/2 * * * /opt/scripts/status.sh
记忆口诀 :五个时间位分别是 分、时、日、月、星期 ,* 表示"每"。
常用日志位置:定时任务的输出默认发邮件,建议重定向到文件:
bash
# 把执行结果写入日志
0 2 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
13.2 at:一次性任务
bash
# 5 分钟后执行
echo "reboot" | at now + 5 minutes
# 指定时间执行
at 23:00
> /opt/scripts/night.sh
> Ctrl+D 结束输入
# 查看待执行任务
atq
# 删除指定任务(编号来自 atq)
atrm 3
13.3 实战:定时备份网站
bash
# 编辑定时任务
crontab -e
# 每天凌晨 3 点把 /var/www 打包备份到 /backup,保留 7 天
0 3 * * * tar -czf /backup/www_$(date +\%Y\%m\%d).tar.gz /var/www && find /backup -name "*.tar.gz" -mtime +7 -delete
注意:cron 中
%需要转义为\%。
13.4 systemd 定时器:cron 的现代替代
新建 /etc/systemd/system/backup.timer:
ini
[Unit]
Description=Daily Backup Timer
[Timer]
OnCalendar=daily # 触发时间
Persistent=true # 错过的时间(如关机)开机后补执行
[Install]
WantedBy=timers.target
bash
# 启用并启动定时器
sudo systemctl enable --now backup.timer
# 查看所有定时器及下次执行时间
systemctl list-timers
# 查看某个定时器状态
systemctl status backup.timer
OnCalendar 常用格式(比 cron 更易读):
ini
OnCalendar=daily # 每天 0 点
OnCalendar=hourly # 每小时
OnCalendar=*-*-* 02:00:00 # 每天凌晨 2 点
OnCalendar=Mon *-*-* 09:00:00 # 每周一早上 9 点
OnCalendar=*-*-1 00:00:00 # 每月 1 号
13.5 crontab 常见坑(务必注意)
bash
# 坑 1:cron 环境变量极少,PATH 默认只有 /usr/bin:/bin
# 脚本里的命令最好写绝对路径
0 2 * * * /usr/local/bin/python3 /opt/scripts/backup.py
# 坑 2:脚本依赖的环境变量(如 JAVA_HOME)要在脚本里自己 export
# 坑 3:任务输出默认会发邮件,容易撑爆邮箱,务必重定向
0 2 * * * /opt/scripts/backup.sh > /dev/null 2>&1
# 坑 4:cron 表达式里的 % 必须转义为 \%
# 错误写法:0 2 * * * date +%Y%m%d
# 正确写法:0 2 * * * date +\%Y\%m\%d
# 坑 5:改完 crontab 用 crontab -l 确认已保存
crontab -l
十四、网络诊断与请求
14.1 连通性测试:ping
bash
# 测试网络连通性(Ctrl+C 停止)
ping www.baidu.com
# 只发 4 个包
ping -c 4 www.baidu.com
# 指定间隔 0.5 秒
ping -i 0.5 192.168.1.1
14.2 域名解析:nslookup / dig
bash
# 查询域名解析结果
nslookup www.baidu.com
# 更详细的解析查询(需安装 dnsutils)
dig www.baidu.com
14.3 连接测试:telnet / nc
bash
# 测试某 IP 的某端口是否开放
telnet 192.168.1.10 3306
# 或使用 nc(netcat)
nc -zv 192.168.1.10 3306
14.4 HTTP 请求:curl(调试接口神器)
bash
# GET 请求
curl https://api.example.com/users
# 保存响应到文件
curl -o resp.json https://api.example.com/users
# 显示响应头
curl -i https://api.example.com/users
# 只显示响应头
curl -I https://api.example.com/users
# POST 请求(提交 JSON 数据)
curl -X POST -H "Content-Type: application/json" \
-d '{"name":"zhangsan","age":25}' \
https://api.example.com/users
# 带认证头
curl -H "Authorization: Bearer TOKEN" https://api.example.com/me
# 下载文件并显示进度
curl -O https://example.com/package.tar.gz
# 测试接口耗时(-w 自定义输出)
curl -o /dev/null -s -w "耗时: %{time_total}s\n" https://api.example.com
14.5 路由与端口
bash
# 查看路由表
route -n
# 或
ip route
# 查看本机 IP
ip addr show
# 或
hostname -I
# 查看网卡流量
iftop
# 查看网络连接状态(替换旧命令 netstat)
ss -tlnp # 监听端口
ss -tn # 所有 TCP 连接
十五、防火墙命令:ufw / firewalld / iptables
15.1 防火墙是什么?
Linux 防火墙基于内核的 netfilter 模块,按规则对进出数据包进行过滤。日常运维接触到的是三套"前端工具":
| 工具 | 适用系统 | 特点 |
|---|---|---|
ufw |
Ubuntu / Debian | 简单易用,一行一个规则 |
firewalld |
CentOS / RHEL 7+ | 支持动态规则、区域(zone)概念 |
iptables |
所有发行版 | 最底层、最强大,规则繁琐 |
15.2 Ubuntu / Debian:ufw
bash
# 查看防火墙状态
sudo ufw status
sudo ufw status verbose
# 启用 / 禁用防火墙
sudo ufw enable
sudo ufw disable
# 放行端口
sudo ufw allow 22
sudo ufw allow 80/tcp
sudo ufw allow 443
# 放行端口范围
sudo ufw allow 8000:8100/tcp
# 拒绝端口
sudo ufw deny 25
# 放行特定 IP 访问
sudo ufw allow from 192.168.1.100
# 放行特定 IP 访问某端口
sudo ufw allow from 192.168.1.100 to any port 3306
# 删除规则
sudo ufw delete allow 80
# 重置所有规则
sudo ufw reset
15.3 CentOS / RHEL:firewalld(firewall-cmd)
bash
# 查看状态
sudo systemctl status firewalld
sudo firewall-cmd --state
# 查看当前已放行的规则
sudo firewall-cmd --list-all
# 放行端口(--permanent 永久生效,否则重启失效)
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=3306/tcp
# 移除端口
sudo firewall-cmd --permanent --remove-port=3306/tcp
# 放行服务(http、https、ssh 等内置服务名)
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=ssh
# 放行端口范围
sudo firewall-cmd --permanent --add-port=8000-8100/tcp
# 放行来源 IP
sudo firewall-cmd --permanent --add-source=192.168.1.100
# 重新加载使规则生效(不中断现有连接)
sudo firewall-cmd --reload
记忆要点 :firewall-cmd 改完规则必须
--reload;不带--permanent只对当前会话生效。
15.4 iptables 基础
bash
# 查看当前规则
sudo iptables -L -n
# 放行某端口(仅内存生效,重启丢失)
sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
# 拒绝某个 IP 的所有请求
sudo iptables -A INPUT -s 1.2.3.4 -j DROP
# 保存规则(Ubuntu 安装 iptables-persistent)
sudo apt install -y iptables-persistent
sudo netfilter-persistent save
15.5 实战:新服务器安全初始化
bash
# Ubuntu:默认拒绝入站,只放行必要端口
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw enable
# CentOS:放行常用服务后重载
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
十六、SSH 远程连接与文件传输
16.1 远程登录:ssh
bash
# 连接远程服务器(默认端口 22)
ssh root@192.168.1.10
# 指定端口连接
ssh -p 2222 root@192.168.1.10
# 指定密钥文件连接
ssh -i ~/.ssh/id_ed25519 root@192.168.1.10
# 连接后执行单条命令并退出
ssh root@192.168.1.10 "df -h && free -h"
首次连接会询问 Are you sure you want to continue connecting?,输入 yes 即可。
16.2 免密登录:配置密钥对
bash
# 1. 在本地生成密钥对(一路回车,可选设置密码短语)
ssh-keygen -t ed25519
# 2. 把公钥复制到服务器(自动追加到 authorized_keys)
ssh-copy-id root@192.168.1.10
# 3. 测试:不再需要密码
ssh root@192.168.1.10
公钥文件:
~/.ssh/id_ed25519.pub(可公开);私钥~/.ssh/id_ed25519(绝不能泄露)。ed25519 比传统 RSA 更安全、速度更快。
16.3 远程传输:scp
bash
# 本地文件上传到服务器
scp file.txt root@192.168.1.10:/home/zhangsan/
# 服务器文件下载到本地
scp root@192.168.1.10:/var/log/nginx/access.log ./
# 递归传输整个目录
scp -r /home/zhangsan/www/ root@192.168.1.10:/var/www/
# 指定端口(注意:scp 用大写 -P,ssh 用小写 -p)
scp -P 2222 file.txt root@192.168.1.10:/tmp/
16.4 增量同步:rsync(推荐)
bash
# 基本同步(-a 归档保留权限属性,-v 显示过程)
rsync -av /home/zhangsan/www/ root@192.168.1.10:/var/www/
# 压缩传输 + 显示进度(-z 压缩,--progress 进度)
rsync -avz --progress /data/ root@192.168.1.10:/backup/
# 双向一致(源端删除的文件,目标端也删除,慎用!)
rsync -av --delete /data/ /backup/
# 排除目录
rsync -av --exclude="node_modules" /project/ /backup/
# 断点续传(大文件传输中断后再次执行即可接着传)
rsync -av --partial /bigfile.iso root@192.168.1.10:/downloads/
rsync 相比 scp 的优势:增量传输(只传变化部分)、支持断点续传、本地目录和远程服务器用法完全一致。
16.5 SSH 安全加固
bash
# 编辑 SSH 服务配置
sudo vim /etc/ssh/sshd_config
# 建议配置项
PermitRootLogin no # 禁止 root 直接登录
PasswordAuthentication no # 只允许密钥登录,禁止密码
Port 2222 # 修改默认端口,减少扫描攻击
AllowUsers zhangsan # 只允许指定用户登录
# 修改配置后必须重启 sshd 生效
sudo systemctl restart sshd
安全提醒:先测试新配置能登录再断开当前连接(改错端口/禁用密码可能导致再也连不上,建议保留一个已连接终端验证)。
十七、日志查看:journalctl 与系统日志
17.1 journalctl 基本用法
systemd 统一收集服务日志,用 journalctl 查询:
bash
# 查看全部日志(默认进入分页模式,q 退出)
journalctl
# 查看某个服务的日志
journalctl -u nginx
# 实时跟踪日志(-f,调试时最常用)
journalctl -u nginx -f
# 查看本次开机以来的日志(-b 当前启动)
journalctl -b
# 查看上一次开机的日志(-b -1)
journalctl -b -1
17.2 按时间过滤
bash
# 最近 10 分钟的日志
journalctl --since "10 min ago"
# 指定时间段
journalctl --since "2026-08-17 09:00" --until "2026-08-17 10:00"
# 昨天的日志
journalctl --since yesterday
# 按关键词过滤(配合管道)
journalctl -u nginx | grep "error"
17.3 传统日志文件
bash
# 常见系统日志
/var/log/messages # 系统综合日志(CentOS/RHEL)
/var/log/syslog # 系统综合日志(Ubuntu)
/var/log/auth.log # 登录认证日志(Ubuntu)
/var/log/secure # 登录认证日志(CentOS)
/var/log/cron # cron 定时任务执行记录
# 应用日志
/var/log/nginx/access.log # nginx 访问日志
/var/log/nginx/error.log # nginx 错误日志
/var/log/mysql/error.log # MySQL 错误日志
bash
# 排查暴力破解:查看失败的登录尝试
grep "Failed password" /var/log/auth.log
# 查看成功登录记录
grep "Accepted" /var/log/auth.log
# 统计尝试登录最多的 IP(防爆破排查)
grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
17.4 日志轮转:logrotate
日志无限增长会撑爆磁盘,用 logrotate 按策略自动切割:
bash
# 全局配置与各软件配置
/etc/logrotate.conf # 全局配置
/etc/logrotate.d/ # 各软件的独立配置
# 示例:/etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily # 每天轮转一次
rotate 30 # 保留 30 份
compress # 旧日志 gzip 压缩
missingok # 日志不存在不报错
notifempty # 空日志不轮转
}
# 手动触发一次轮转验证配置
sudo logrotate -f /etc/logrotate.conf
十八、磁盘与内存监控
18.1 磁盘空间:df
bash
# 查看磁盘总占用(人类可读格式)
df -h
# 查看指定目录所在分区的空间
df -h /home
# 只看文件系统类型
df -T
输出示例:
文件系统 容量 已用 可用 已用% 挂载点
/dev/sda1 100G 45G 55G 46% /
tmpfs 7.8G 12M 7.8G 1% /dev/shm
18.2 目录大小:du
bash
# 查看当前目录总大小
du -sh
# 查看当前目录下每个子目录的大小
du -sh *
# 查看指定目录大小
du -sh /var/log
# 排序显示最大的前 10 个目录
du -sh * | sort -rh | head -10
实战:服务器磁盘满了,快速定位"罪魁祸首":
bash
# 一层层找最大的目录
du -h --max-depth=1 / 2>/dev/null | sort -rh | head -10
# 或者用 --max-depth 控制层级
du -h --max-depth=2 /var 2>/dev/null | sort -rh | head
18.3 内存:free
bash
# 查看内存使用(人类可读)
free -h
# 输出示例
# total used free shared buff/cache available
# Mem: 15Gi 2.1Gi 9.8Gi 89Mi 3.5Gi 13Gi
# Swap: 2.0Gi 0B 2.0Gi
看内存是否够用,关注 available(可用)而不是 free------Linux 会用空闲内存做缓存(buff/cache),需要时会自动释放。
18.4 实时监控
bash
# 动态监控系统整体(CPU/内存/负载/进程)
top
# 更友好的监控
htop
# 查看系统负载(1/5/15 分钟平均)
uptime
# 输出:13:14:22 up 3 days, 2:31, 2 users, load average: 0.08, 0.03, 0.01
18.5 系统信息:uname / lscpu / hostnamectl
bash
# 内核版本与系统架构
uname -a
# 只看内核版本
uname -r
# CPU 信息(型号、核心数、频率)
lscpu
# 主机名与操作系统信息
hostnamectl
# 查看发行版版本信息
cat /etc/os-release
# 系统运行时间与负载
uptime
# 日期时间(可自定义格式)
date
date "+%Y-%m-%d %H:%M:%S"
# 查看系统时间是否同步
timedatectl
十九、压缩打包:tar 与 zip
19.1 tar:打包 + 压缩一步到位
bash
# 打包并 gzip 压缩(-c 创建,-z gzip,-v 显示过程,-f 指定文件名)
tar -czvf backup.tar.gz /home/zhangsan/www/
# 解压到当前目录(-x 解压)
tar -xzvf backup.tar.gz
# 解压到指定目录(-C 指定目录)
tar -xzvf backup.tar.gz -C /opt/www/
# 只打包不压缩
tar -cvf backup.tar /home/zhangsan/www/
# 查看压缩包内容(不解压)
tar -tzvf backup.tar.gz
# 追加文件到 tar 包(不压缩的包才行)
tar -rvf backup.tar newfile.txt
# 使用 bzip2 压缩(体积更小,速度更慢)
tar -cjvf backup.tar.bz2 /home/zhangsan/www/
# 使用 xz 压缩(体积最小)
tar -cJvf backup.tar.xz /home/zhangsan/www/
# 排除某些文件打包
tar -czvf backup.tar.gz /var/www --exclude="*.log" --exclude="cache/"
记忆口诀 :
czvf压缩、xzvf解压、tzvf查看。参数顺序基本固定:tar -c/z/x + v + f 文件名。
19.2 zip / unzip
bash
# 压缩(-r 递归目录)
zip -r archive.zip mydir/
# 指定压缩级别(0-9,9 最高压缩率)
zip -9 -r archive.zip mydir/
# 解压
unzip archive.zip
# 解压到指定目录
unzip archive.zip -d /opt/target/
# 查看压缩包内容
unzip -l archive.zip
# 带密码压缩
zip -P 123456 -r secret.zip mydir/
19.3 其他压缩命令
bash
# 单独 gzip(会删除原文件,通常配合 tar 使用)
gzip file.txt # 生成 file.txt.gz,原文件消失
gunzip file.txt.gz # 解压
# bzip2
bzip2 file.txt
bunzip2 file.txt.bz2
# 直接查看压缩文件内容
zcat file.txt.gz
zless app.log.gz
二十、软件包管理:apt / yum / dnf
20.1 Debian / Ubuntu:apt
bash
# 更新软件源索引
sudo apt update
# 升级所有已安装软件
sudo apt upgrade
# 安装软件
sudo apt install nginx
# 安装多个软件
sudo apt install git curl vim -y
# 卸载软件(保留配置文件)
sudo apt remove nginx
# 彻底卸载(连配置文件一起删)
sudo apt purge nginx
# 清理无用依赖
sudo apt autoremove
# 搜索软件
apt search python3
# 查看已安装软件
apt list --installed | grep nginx
20.2 RHEL / CentOS:yum / dnf
bash
# 安装
sudo yum install nginx
# 搜索
yum search nginx
# 卸载
sudo yum remove nginx
# 更新
sudo yum update
# CentOS 8+ 使用 dnf(用法与 yum 相同)
sudo dnf install git
20.3 源码编译安装(终极方案)
当官方源里没有、或需要特定版本时,源码编译安装:
bash
# 1. 下载源码
wget https://example.com/software-1.2.3.tar.gz
# 2. 解压
tar -xzvf software-1.2.3.tar.gz
cd software-1.2.3
# 3. 配置(--prefix 指定安装位置)
./configure --prefix=/usr/local/software
# 4. 编译(-j4 用 4 个核并行)
make -j4
# 5. 安装(需要 root)
sudo make install
20.4 常用软件一行装
bash
# Ubuntu 全家桶
sudo apt install -y vim git curl wget tree htop net-tools lsof unzip
# 装 Python 开发环境
sudo apt install -y python3 python3-pip
# 装 Node.js(推荐用 nvm 管理版本)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm install --lts
二十一、Shell 常用技巧与快捷键
21.1 高频快捷键
| 快捷键 | 作用 |
|---|---|
Tab |
自动补全命令/文件名(连按两次列出所有候选) |
Ctrl+C |
终止当前命令 |
Ctrl+D |
退出当前终端 / EOF |
Ctrl+L |
清屏(等价 clear) |
Ctrl+A |
光标跳到行首 |
Ctrl+E |
光标跳到行尾 |
Ctrl+U |
删除光标到行首 |
Ctrl+K |
删除光标到行尾 |
Ctrl+W |
删除光标前一个单词 |
↑ / ↓ |
历史命令上下翻 |
Ctrl+R |
反向搜索历史命令(神器!) |
bash
# Ctrl+R 的典型用法
# 输入:systemctl restart
# 自动匹配历史中最近的 systemctl restart nginx
21.2 重定向
bash
# 覆盖写入文件
echo "hello" > file.txt
# 追加写入文件
echo "world" >> file.txt
# 错误输出也写入文件(2>&1 顺序不能反)
command 2>&1 | tee output.log
# 同时输出到屏幕和文件
command | tee output.log
# 丢弃所有输出(/dev/null 是黑洞)
command > /dev/null 2>&1
21.3 历史命令
bash
# 查看历史
history
# 执行第 N 条命令
!100
# 执行上一条命令
!!
# 执行上一条以 echo 开头的命令
!echo
# 清除历史
history -c
21.4 变量与别名
bash
# 定义变量(注意 = 两边不能有空格)
name="zhangsan"
echo $name
# 环境变量
export PATH=$PATH:/usr/local/bin
# 常用环境变量
echo $HOME # 家目录
echo $PATH # 命令搜索路径
echo $USER # 当前用户
echo $HOSTNAME # 主机名
# 定义别名(重启失效,写入 ~/.bashrc 永久生效)
alias ll='ls -lah'
alias rm='rm -i'
alias grep='grep --color'
# 让别名永久生效
echo "alias ll='ls -lah'" >> ~/.bashrc
source ~/.bashrc
21.5 一行多命令
bash
# 分号:无论成败都执行
cd /tmp; pwd; ls
# &&:前一个成功才执行后一个
cd /opt && make && sudo make install
# ||:前一个失败才执行后一个
command1 || echo "命令失败了"
# 组合:成功打印 OK,失败打印 FAIL
command && echo "OK" || echo "FAIL"
二十二、高频实战场景演练
22.1 场景一:排查 CPU 飙升
bash
# 1. 看整体负载
top
# 2. 找出 CPU 占用最高的进程(P 键按 CPU 排序)
top -c
# 3. 或一行命令输出 Top 5
ps aux --sort=-%cpu | head -6
# 4. 找到进程后查看其线程
top -H -p PID
# 5. 看该进程正在做什么
strace -p PID -c # 需安装 strace,Ctrl+C 后统计系统调用
22.2 场景二:磁盘满了怎么办
bash
# 1. 确认哪个分区满了
df -h
# 2. 找最大的目录
du -h --max-depth=1 /var 2>/dev/null | sort -rh | head
# 3. 找最大的文件
find /var -type f -size +500M -exec ls -lh {} \; 2>/dev/null
# 4. 清理日志(truncate 保留文件,只清内容,推荐)
sudo truncate -s 0 /var/log/nginx/access.log
# 5. 清理包缓存
sudo apt clean
sudo yum clean all
# 6. 查找被删除但仍占用空间的文件(删除后进程还持有)
lsof | grep deleted
22.3 场景三:日志实时监控与统计
bash
# 实时看错误日志
tail -f /var/log/app.log | grep ERROR
# 统计最近 1 小时错误次数
grep "$(date -d '1 hour ago' '+%Y-%m-%d %H')" app.log | grep -c ERROR
# 统计访问量 Top 10 的 URL
awk '{print $7}' access.log | sort | uniq -c | sort -rn | head -10
# 统计 HTTP 状态码分布
awk '{print $9}' access.log | sort | uniq -c | sort -rn
# 找出响应超过 3 秒的请求($10 是响应时间列,按实际格式调整)
awk '$10 > 3 {print $1, $7, $10}' access.log
22.4 场景四:批量重命名文件
bash
# 把所有 .txt 改为 .md(用 rename 或循环)
for f in *.txt; do mv "$f" "${f%.txt}.md"; done
# 批量加前缀
for f in *.jpg; do mv "$f" "photo_$f"; done
# 批量替换文件名中的空格(推荐用 tr)
for f in *; do mv "$f" "$(echo "$f" | tr ' ' '_')"; done
# 用 find + sed 批量改名
find . -name "*.bak" -exec rename 's/\.bak$/.old/' {} \;
22.5 场景五:服务器一键体检
bash
# 写一个简单的体检脚本 check.sh
#!/bin/bash
echo "===== 系统负载 ====="
uptime
echo "===== 内存使用 ====="
free -h
echo "===== 磁盘使用 ====="
df -h | grep -v tmpfs
echo "===== CPU 占用 Top 5 ====="
ps aux --sort=-%cpu | head -6
echo "===== 监听端口 ====="
ss -tlnp
echo "===== 失败登录尝试 ====="
grep "Failed password" /var/log/auth.log 2>/dev/null | tail -5
bash
# 保存后执行
chmod +x check.sh && ./check.sh
二十三、总结与速查表
23.1 高频命令速查
| 命令 | 一句话功能 | 示例 |
|---|---|---|
ls |
列出文件 | ls -lah |
cd |
切换目录 | cd /var/log |
pwd |
当前路径 | pwd |
cat |
查看文件 | cat /etc/hosts |
tail -f |
实时看日志 | tail -f app.log |
grep |
搜索文本 | grep ERROR app.log |
find |
查找文件 | find / -name "*.conf" |
cp / mv / rm |
复制/移动/删除 | cp -r a b |
mkdir |
创建目录 | mkdir -p a/b |
chmod |
修改权限 | chmod 755 script.sh |
chown |
修改属主 | chown user:group file |
ps aux |
查看进程 | `ps aux |
kill |
终止进程 | kill -9 1234 |
top / htop |
动态监控 | top |
df -h / du -sh |
磁盘空间 | df -h |
free -h |
内存使用 | free -h |
ping / curl |
连通/请求 | curl -I baidu.com |
ss -tlnp |
查看端口 | ss -tlnp |
tar -czvf |
压缩打包 | tar -czvf b.tar.gz dir |
systemctl |
服务管理 | systemctl restart nginx |
ufw |
Ubuntu 防火墙 | sudo ufw allow 80/tcp |
firewall-cmd |
CentOS 防火墙 | firewall-cmd --permanent --add-port=80/tcp |
ssh |
远程连接 | ssh root@192.168.1.10 |
scp / rsync |
远程传输 | rsync -av dir user@host:/path |
journalctl |
查看服务日志 | journalctl -u nginx -f |
stat |
查看文件元数据 / inode | stat file.txt |
df -i |
查看 inode 用量 | df -i |
lsof |
查看进程 / 端口 / 文件占用 | lsof -i :80 |
tcpdump |
网络抓包 | tcpdump -i eth0 port 80 |
ip addr |
查看网卡与 IP | ip addr |
nc |
端口探测 | nc -zv host 22 |
23.2 命令组合万能公式
bash
# 查找 → 过滤 → 统计 → 排序 → 取前 N
find . -name "*.log" | grep "ERROR" | wc -l
ps aux | grep java | awk '{print $2}' | xargs kill
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
23.3 进阶方向
| 方向 | 内容 | 价值 |
|---|---|---|
| Shell 脚本 | 变量、条件、循环、函数 | 自动化运维的基础 |
| Vim 编辑器 | 掌握常用模式与命令 | 服务器上没有图形界面也能高效编辑 |
| 网络原理 | TCP/IP、DNS、HTTP | 排查问题的底层功底 |
| 容器化 | Docker、docker-compose | 现代部署的标配 |
| 云上运维 | 云主机、负载均衡、监控告警 | 生产环境的工程化能力 |
| 文件系统原理 | inode、挂载、日志文件系统 | 磁盘故障排查的底层知识 |
| 网络抓包 | tcpdump、Wireshark | 定位疑难网络问题的利器 |
23.4 知识体系全景图
#mermaid-svg-HD8R9sUo1AvLyoGv{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HD8R9sUo1AvLyoGv .error-icon{fill:#552222;}#mermaid-svg-HD8R9sUo1AvLyoGv .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HD8R9sUo1AvLyoGv .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HD8R9sUo1AvLyoGv .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HD8R9sUo1AvLyoGv .marker.cross{stroke:#333333;}#mermaid-svg-HD8R9sUo1AvLyoGv svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HD8R9sUo1AvLyoGv p{margin:0;}#mermaid-svg-HD8R9sUo1AvLyoGv .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-HD8R9sUo1AvLyoGv .cluster-label text{fill:#333;}#mermaid-svg-HD8R9sUo1AvLyoGv .cluster-label span{color:#333;}#mermaid-svg-HD8R9sUo1AvLyoGv .cluster-label span p{background-color:transparent;}#mermaid-svg-HD8R9sUo1AvLyoGv .label text,#mermaid-svg-HD8R9sUo1AvLyoGv span{fill:#333;color:#333;}#mermaid-svg-HD8R9sUo1AvLyoGv .node rect,#mermaid-svg-HD8R9sUo1AvLyoGv .node circle,#mermaid-svg-HD8R9sUo1AvLyoGv .node ellipse,#mermaid-svg-HD8R9sUo1AvLyoGv .node polygon,#mermaid-svg-HD8R9sUo1AvLyoGv .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HD8R9sUo1AvLyoGv .rough-node .label text,#mermaid-svg-HD8R9sUo1AvLyoGv .node .label text,#mermaid-svg-HD8R9sUo1AvLyoGv .image-shape .label,#mermaid-svg-HD8R9sUo1AvLyoGv .icon-shape .label{text-anchor:middle;}#mermaid-svg-HD8R9sUo1AvLyoGv .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HD8R9sUo1AvLyoGv .rough-node .label,#mermaid-svg-HD8R9sUo1AvLyoGv .node .label,#mermaid-svg-HD8R9sUo1AvLyoGv .image-shape .label,#mermaid-svg-HD8R9sUo1AvLyoGv .icon-shape .label{text-align:center;}#mermaid-svg-HD8R9sUo1AvLyoGv .node.clickable{cursor:pointer;}#mermaid-svg-HD8R9sUo1AvLyoGv .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HD8R9sUo1AvLyoGv .arrowheadPath{fill:#333333;}#mermaid-svg-HD8R9sUo1AvLyoGv .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HD8R9sUo1AvLyoGv .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HD8R9sUo1AvLyoGv .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HD8R9sUo1AvLyoGv .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HD8R9sUo1AvLyoGv .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HD8R9sUo1AvLyoGv .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HD8R9sUo1AvLyoGv .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HD8R9sUo1AvLyoGv .cluster text{fill:#333;}#mermaid-svg-HD8R9sUo1AvLyoGv .cluster span{color:#333;}#mermaid-svg-HD8R9sUo1AvLyoGv div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HD8R9sUo1AvLyoGv .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HD8R9sUo1AvLyoGv rect.text{fill:none;stroke-width:0;}#mermaid-svg-HD8R9sUo1AvLyoGv .icon-shape,#mermaid-svg-HD8R9sUo1AvLyoGv .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HD8R9sUo1AvLyoGv .icon-shape p,#mermaid-svg-HD8R9sUo1AvLyoGv .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HD8R9sUo1AvLyoGv .icon-shape .label rect,#mermaid-svg-HD8R9sUo1AvLyoGv .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HD8R9sUo1AvLyoGv .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HD8R9sUo1AvLyoGv .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HD8R9sUo1AvLyoGv :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 原理进阶
运维日常
核心能力
入门
命令基础
目录路径
文件与目录
文本三剑客
权限与用户
进程 / systemctl / 定时任务
网络 / 防火墙 / SSH
磁盘 / 日志 / 压缩
文件系统 inode
抓包排查
面试考点 / 踩坑 / 发行版对照
至此,你已经掌握了 Linux 日常使用中最核心的命令与套路。学习 Linux 没有捷径,就是多敲 :把上面的例子亲手跑一遍,再试着用组合命令解决自己的实际问题(比如分析自己的网站日志)。遇到不会的命令就
man它、--help它,用多了自然就熟了。想继续深挖,可以回头精读第二十四至二十八章的原理、面试与避坑内容。祝学习顺利!
二十四、文件系统与 inode:理解 Linux 如何存储文件
24.1 一切皆文件:Linux 的文件类型
Linux 哲学的第一条就是一切皆文件 :普通文件、目录、设备、管道、套接字都是文件。用 ls -l 看输出第一个字符就能区分类型:
bash
$ ls -l /dev/sda /etc/passwd /bin/ls /dev/null
brw-rw---- 1 root disk 8, 0 11月 8 10:00 /dev/sda # b 块设备
-rw-r--r-- 1 root root 2906 11月 8 09:00 /etc/passwd # - 普通文件
-rwxr-xr-x 1 root root 161304 11月 8 08:00 /bin/ls # - 普通可执行文件
crw-rw-rw- 1 root root 1, 3 11月 8 10:00 /dev/null # c 字符设备
| 首字符 | 类型 | 例子 | 说明 |
|---|---|---|---|
- |
普通文件 | /etc/passwd |
文本、二进制、脚本等 |
d |
目录 | /home |
本质是"目录项→inode"的映射表 |
l |
软链接 | /bin/sh -> bash |
指向另一个文件的"快捷方式" |
b |
块设备 | /dev/sda |
按块读写,如硬盘、SSD |
c |
字符设备 | /dev/null |
按字符流读写,如终端、串口 |
s |
套接字 | /run/nginx.sock |
进程间通信 |
p |
命名管道 | /tmp/fifo |
进程间通信 |
不确定类型时用 file 命令,它会读取文件头特征智能识别:
bash
file /etc/passwd # ASCII text
file /bin/ls # ELF 64-bit LSB executable
file logo.png # PNG image data
24.2 inode:文件的"身份证"
一个文件由三部分组成:目录项(文件名)→ inode(元数据)→ 数据块(内容) 。inode 记录了文件的权限、属主、大小、时间戳、数据块位置等,但不含文件名------文件名只存在于目录项中。
bash
# stat 查看文件的 inode 全量信息
$ stat /etc/passwd
文件:/etc/passwd
大小:2906 块:8 IO 块:4096 普通文件
设备:fd00h/64768d Inode:1305618 硬链接:1
权限:(0644/-rw-r--r--) Uid:( 0/ root) Gid:( 0/ root)
最近访问:2026-08-17 10:00:01
最近更改:2026-08-17 09:00:00
最近改动:2026-08-17 09:00:00
创建时间:2026-08-10 08:00:00
# 只查 inode 编号(ls -i)
ls -i /etc/passwd # 1305618 /etc/passwd
硬链接与软链接的本质区别就在这里:
| 对比项 | 硬链接 | 软链接(符号链接) |
|---|---|---|
| inode | 与原文件共用同一个 inode | 独立 inode,内容是目标路径 |
| 删除原文件 | 链接依然有效 | 链接失效(红底白字) |
| 跨文件系统 | 不支持 | 支持 |
| 目录 | 一般不允许 | 允许 |
| 创建命令 | ln a.txt a_hard |
ln -s a.txt a_soft |
bash
echo "hello" > a.txt
ln a.txt a_hard # 硬链接:两个名字指向同一 inode
ln -s a.txt a_soft # 软链接:快捷方式
ls -i a.txt a_hard a_soft
# 1305700 a.txt 1305700 a_hard 1305701 a_soft
# 注意 a.txt 与 a_hard 的 inode 相同,a_soft 不同
rm a.txt # 删除原文件
cat a_hard # 输出 hello(硬链接不受影响)
cat a_soft # 报错:No such file or directory(软链接失效)
用一张图理解三者的关系:
渲染错误: Mermaid 渲染失败: Parse error on line 4: ...inode] -.存储的是路径字符串 "a.txt".-> inode -----------------------^ Expecting 'LINK', 'UNICODE_TEXT', 'EDGE_TEXT', got 'STR'
硬链接数是 inode 的重要字段 :stat 里的"硬链接"数量,每多一个硬链接就 +1,删除文件实际是"硬链接数减 1,减到 0 才真正释放数据块"。这也是 lsof | grep deleted 能查到"已删除但仍被进程占用"文件的原因------进程还持有这个 inode。
24.3 经典故障:磁盘没满,却报"No space left on device"
这是运维面试高频题!磁盘满(block 耗尽)和 inode 耗尽都会报这个错,但表现不同:
bash
# 1. 先看磁盘块用量(平时看这个)
df -h
# 2. 再看 inode 用量(小文件太多时会爆)
df -i
# Filesystem Inodes IUsed IFree IUse% Mounted on
# /dev/sda1 1310720 1310720 0 100% / ← inode 满了!
inode 耗尽的典型场景 :邮件队列、/var/spool、Docker overlay 目录、日志切割残留的百万小文件。排查与处理:
bash
# 统计根分区下哪个目录文件最多(xdev 限定同一文件系统,避免跨盘)
find / -xdev -type f | cut -d/ -f2 | sort | uniq -c | sort -rn | head
# 定位小文件最多的目录
find /var/spool -xdev -type f | wc -l
# 处理:删除无用的小文件 / 归档
find /var/spool/old -type f -mtime +90 -delete
一句话总结:df -h 看容量、df -i 看 inode 数,排查"No space left"时两个都查。
24.4 分区与挂载常用命令
| 命令 | 功能 | 示例 |
|---|---|---|
lsblk |
树形查看块设备 | lsblk |
fdisk -l |
查看/管理分区表 | sudo fdisk -l /dev/sdb |
mkfs.ext4 |
格式化分区 | sudo mkfs.ext4 /dev/sdb1 |
mount |
挂载 | sudo mount /dev/sdb1 /data |
umount |
卸载 | sudo umount /data |
blkid |
查看分区的 UUID 与类型 | sudo blkid |
df -hT |
查看挂载点与文件系统类型 | df -hT |
开机自动挂载 要写 /etc/fstab,按 UUID 挂载最稳(盘符可能变,UUID 不变):
bash
# 先用 blkid 查出 UUID
sudo blkid /dev/sdb1
# 编辑 /etc/fstab,追加一行(<设备> <挂载点> <类型> <选项> <dump> <fsck>)
UUID=xxxx-xxxx /data ext4 defaults 0 2
# 校验 fstab 语法后立即挂载(推荐:写错会导致开机起不来)
sudo mount -a
安全提醒 :
mkfs会格式化清空数据;改/etc/fstab前务必备份,并用mount -a验证。
二十五、网络抓包与连接排查:tcpdump / ss / lsof / ip
25.1 ip 命令:现代网络配置标配
老命令 ifconfig 已不维护,现代系统用 ip 全家桶:
bash
# 查看所有网卡与 IP(等价 ifconfig -a)
ip addr
# 只看某个网卡
ip addr show eth0
# 查看路由表(等价 route -n)
ip route
# 查看网卡链路状态
ip link
# 临时启用/禁用网卡
sudo ip link set eth0 up
sudo ip link set eth0 down
常用对照 :ifconfig eth0 → ip addr show eth0;route -n → ip route;arp -a → ip neigh。
25.2 ss:端口与连接状态一网打尽
ss 是 netstat 的现代替代,更快更准(生产环境优先用 ss):
bash
# 查看所有 TCP 监听端口(含进程)
ss -tlnp
# 查看所有 UDP 监听
ss -ulnp
# 按状态过滤(如统计处于 TIME_WAIT 的连接)
ss -tan state TIME_WAIT
# 连接状态汇总(一眼看出 SYN 积压、连接数异常)
ss -s
# Total: 312 (kernel 0)
# TCP: 58 (estab 23, closed 20, orphaned 0, timewait 20)
排查"端口被占用"的标准姿势:
bash
# 谁占用了 8080 端口
ss -tlnp | grep 8080
# LISTEN 0 128 0.0.0.0:8080 0.0.0.0:* users:(("java",pid=12345,fd=98))
# 杀掉占用进程
kill -9 12345
25.3 lsof:进程 ↔ 文件 ↔ 端口的"关系网"
bash
# 查看 80 端口被谁监听
lsof -i :80
# 查看某个进程打开了哪些文件
lsof -p 12345
# 查看某文件被哪些进程占用(典型:卸载磁盘失败时)
lsof /data
# 查看被删除但仍被进程占用的文件(磁盘满排查神器)
lsof | grep deleted
经典场景 :日志被 rm 了但磁盘空间没释放------因为进程还握着文件句柄。处理:
bash
# 找到持有者进程
lsof | grep deleted
# java 12345 root 3w REG 8,1 2048000000 524288 /var/log/app.log (deleted)
# 方案一:重启进程释放(推荐)
# 方案二:truncate 清空(文件已删无法用,直接 kill 进程)
kill -9 12345 && df -h # 空间立即释放
25.4 tcpdump 抓包实战
抓包是定位疑难网络问题的终极手段,语法:tcpdump [选项] [过滤表达式]:
bash
# 常用选项
-i eth0 # 指定网卡(-i any 抓所有)
-nn # 不做 DNS/端口名解析(更清晰)
-c 10 # 只抓 10 个包就退出
-w a.pcap # 保存到文件(用 Wireshark 打开分析)
-r a.pcap # 读取文件
# 抓 80 端口的 HTTP 流量
sudo tcpdump -i any -nn port 80
# 抓指定主机的双向流量
sudo tcpdump -i eth0 -nn host 192.168.1.100
# 组合过滤:and / or / not
sudo tcpdump -i any -nn port 80 and host 192.168.1.100
sudo tcpdump -i any -nn tcp port 22 and not host 10.0.0.1
# 抓 TCP 三次握手(指定端口 + 只看 SYN/SYN-ACK/ACK 标志位)
sudo tcpdump -i any -nn tcp port 8080 and 'tcp[tcpflags] & tcp-syn != 0'
# 抓 DNS 查询(UDP 53 端口)
sudo tcpdump -i any -nn udp port 53
# 抓 ping(ICMP)
sudo tcpdump -i any -nn icmp
抓三次握手看连接建立过程(两台机器各开一个终端):
bash
# 终端 A:开始抓包
sudo tcpdump -i any -nn tcp port 8080 -c 3
# 终端 B:发起连接
curl http://10.0.0.5:8080/
# 终端 A 输出(关键看 SYN → SYN-ACK → ACK 三步)
# 10.0.0.6.52001 > 10.0.0.5.8080: Flags [S] ← 客户端发 SYN
# 10.0.0.5.8080 > 10.0.0.6.52001: Flags [S.] ← 服务端回 SYN-ACK
# 10.0.0.6.52001 > 10.0.0.5.8080: Flags [.] ← 客户端回 ACK,三次握手完成
25.5 端口不通排查五步法(面试必答套路)
| 步骤 | 命令 | 排查什么 |
|---|---|---|
| ① 服务监听了吗 | `ss -tlnp | grep 8080` |
| ② 本机能通吗 | curl 127.0.0.1:8080 |
排除服务本身问题 |
| ③ 防火墙放行了吗 | sudo ufw status / firewall-cmd --list-all |
端口被防火墙拦截 |
| ④ 跨主机能通吗 | nc -zv 目标IP 8080 |
网络路由 / 安全组 |
| ⑤ 抓包看包到没到 | tcpdump -i any port 8080 |
包没到 = 网络/安全组问题;包到了连不上 = 服务/防火墙问题 |
bash
# nc 端口探测(-z 只探测不发送数据,-v 显示详情)
nc -zv 192.168.1.10 22
# Connection to 192.168.1.10 port 22 [tcp/ssh] succeeded!
# telnet 也可以(老办法)
telnet 192.168.1.10 22
二十六、高频面试考点速答
面试官最爱问的 Linux 命令题,答案直接背。每道题都给出"一句话答案 + 演示命令"。
26.1 文件与权限类
Q1:硬链接和软链接的区别?
一句话答案:硬链接共享同一个 inode,删除原文件仍有效;软链接是存路径的独立文件,原文件删除即失效,且支持跨文件系统。
bash
ln a.txt hard # 硬链接
ln -s a.txt soft # 软链接
ls -i a.txt hard soft # 前两者 inode 相同,soft 不同
Q2:chmod 754 file 是什么权限?
7=rwx(属主)、5=r-x(属组)、4=r--(其他人),即属主可读写执行、属组可读执行、其他人只读。
bash
chmod 754 script.sh
ls -l script.sh # -rwxr-xr--
Q3:find 和 grep 的区别?
find 按文件名/大小/时间 找文件;grep 按文件内容搜文本。
bash
find /etc -name "*.conf" # 找文件名匹配的
grep -r "timeout" /etc/ # 搜内容包含的
Q4:> 与 >>、2> 的区别?
> 覆盖写入、>> 追加、2> 重定向错误输出。
bash
echo 1 > a.txt # 覆盖
echo 2 >> a.txt # 追加
ls /no/such 2>err.log # 错误信息进 err.log
26.2 文本处理类
Q5:grep / sed / awk 各自擅长什么?
grep 擅长筛选行 ;sed 擅长替换/删除行 ;awk 擅长按列统计、取字段、格式化输出。
bash
grep ERROR app.log # 筛行
sed 's/ERROR/WARN/g' app.log # 替换
awk '{print $1, $NF}' app.log # 取第一列和最后一列
Q6:统计 access.log 里访问量 Top 10 的 IP?
经典组合:awk 取列 → sort → uniq -c → sort -rn → head。
bash
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
Q7:怎么把 a,b,c,d 按逗号分割取第 2 个字段?
bash
echo "a,b,c,d" | awk -F',' '{print $2}' # b
echo "a,b,c,d" | cut -d',' -f2 # b
26.3 进程与系统类
Q8:什么是僵尸进程?怎么处理?
子进程结束而父进程未 wait 回收,进程就变僵尸(Z 状态)。处理:找到父进程并重启它,或用 kill 向父进程发信号(僵尸本身杀不掉)。
bash
ps aux | awk '$8=="Z"' # 找出僵尸进程
ps -o ppid= -p <PID> # 找父进程
kill -9 <父进程PID> # 父进程没了,僵尸由 init 接管回收
Q9:nohup cmd & 和 cmd & 的区别?
& 只是后台运行,关终端(挂断)进程会被杀;nohup 忽略挂断信号,即使退出终端也继续跑。生产环境两者一起用。
bash
nohup java -jar app.jar > app.log 2>&1 &
Q10:top 里 %CPU、load average 怎么看?
%CPU 是单核占用(200% 表示用了 2 核);load average 是 1/5/15 分钟的平均运行队列长度,超过 CPU 核数说明过载。
bash
top # 交互:按 P 按 CPU 排序、按 M 按内存排序
uptime # 直接看 load average
nproc # CPU 核数(对比 load 用)
Q11:端口被占用怎么排查?
bash
ss -tlnp | grep 8080 # 找到 pid
lsof -i :8080 # 或者用 lsof
kill -9 <pid>
26.4 网络与综合类
Q12:curl -I 和 curl -v 区别?
-I 只发 HEAD 请求看响应头;-v 显示完整请求/响应过程(含 TLS 握手、DNS 解析)。
bash
curl -I https://example.com # 只看响应头
curl -v https://example.com # 看全过程
Q13:如何验证 DNS 解析、TCP 连通、HTTP 服务三个层级?
bash
nslookup example.com # ① DNS 层
nc -zv example.com 443 # ② TCP 层
curl -I example.com # ③ HTTP 层
Q14:写一条命令,找出服务器上 CPU 占用最高的进程?
bash
ps aux --sort=-%cpu | head -2
# 或
top -bn1 | head -12 | tail -6
Q15:一条命令杀掉所有 nginx 进程?
bash
pkill -f nginx
# 或
ps aux | grep nginx | grep -v grep | awk '{print $2}' | xargs kill
Q16:如何查看系统开机时间与内核版本?
bash
uptime -s # 开机时间
uname -a # 内核版本
cat /etc/os-release # 发行版信息
二十七、踩坑锦集:新手最容易犯的 12 个错误
这些坑每一个都是真实生产事故的缩影,看完能帮你少走几个月弯路。
27.1 踩坑总览表
| # | 坑 | 后果 | 正确姿势 |
|---|---|---|---|
| 1 | rm -rf $VAR/ 变量为空 |
删到根目录 | 删前 echo $VAR,加 set -u |
| 2 | 空格文件名不引号 | 一个文件拆成两个 | 路径永远加双引号 |
| 3 | crontab 里命令找不到 | 定时任务静默失败 | 用绝对路径 / 脚本开头 source 环境 |
| 4 | 写脚本忘了 chmod +x |
提示 Permission denied | 记得授权 |
| 5 | `sudo cat a | tee b` 顺序错 | 写入仍报权限不足 |
| 6 | 变量赋值 name = xxx |
报 command not found | 等号两侧不能有空格 |
| 7 | grep 没匹配到就以为没事 |
漏掉真实故障 | 先 wc -l 确认匹配数 |
| 8 | 磁盘满和 inode 满混为一谈 | 查半天查不出 | 同时看 df -h 与 df -i |
| 9 | find 的 * 不匹配隐藏文件 |
清理不彻底 | 加 -name ".*" 或 -maxdepth |
| 10 | tail -f 退不出 |
卡死终端 | Ctrl+C 退出 |
| 11 | 软链接用相对路径 | 链接失效 | 用绝对路径或 $PWD |
| 12 | 误以为 kill 一定立即生效 |
进程还在 | 先 TERM 后 KILL,ps 确认 |
27.2 高危操作类(必须刻进 DNA)
坑 1:rm -rf 遇到变量为空 → 灾难
bash
# ❌ 危险写法:DIR 为空时等价于 rm -rf /
DIR=""; rm -rf $DIR/
# ✅ 安全写法:删前打印确认 + 变量判空
echo "将删除: $DIR"
[ -z "$DIR" ] && echo "变量为空,拒绝执行" && exit 1
rm -rf "$DIR/"
坑 2:文件名带空格被拆词
bash
# ❌ 错误:my file.txt 被当成两个文件
rm my file.txt
# ✅ 正确:加引号
rm "my file.txt"
坑 5:管道后 sudo 不生效
bash
# ❌ 错误:sudo 只作用于 cat,tee 仍以普通用户写 /etc
sudo cat /etc/nginx/nginx.conf > /etc/nginx/backup.conf
# ✅ 正确一:sudo 作用于 tee
cat /etc/nginx/nginx.conf | sudo tee /etc/nginx/backup.conf
# ✅ 正确二:整体用 bash -c
sudo bash -c 'cat /etc/nginx/nginx.conf > /etc/nginx/backup.conf'
27.3 脚本编写类
坑 3:crontab 环境变量缺失
cron 执行环境极简(PATH 只有 /usr/bin:/bin),你的 python3、node 可能根本不在 PATH 里:
bash
# ❌ 错误:任务静默失败,日志什么都没有
* * * * * python3 /opt/script.py
# ✅ 正确:脚本第一行 source 环境,或用绝对路径
* * * * * /usr/bin/python3 /opt/script.py >> /tmp/script.log 2>&1
# 或者脚本内用全路径:
# /opt/script.py 第一行写 #!/usr/bin/python3
坑 6:变量赋值等号两侧不能有空格
bash
# ❌ 错误:bash 会当成"执行 name 命令"
name = "zhangsan"
# ✅ 正确
name="zhangsan"
坑 4:脚本没执行权限
bash
# ❌ 错误
./check.sh # bash: ./check.sh: Permission denied
# ✅ 正确:授权后执行
chmod +x check.sh && ./check.sh
27.4 命令理解类
坑 7:grep 无输出 ≠ 没有匹配,也可能是文件不存在
bash
# ❌ 错误:直接凭直觉判断
grep ERROR app.log
# ✅ 正确:先确认文件存在与匹配数
ls -l app.log
grep -c ERROR app.log # 输出 0 才说明真的没有
坑 9:find 的 * 不匹配隐藏文件
bash
# ❌ 错误:清理 .cache 下的隐藏文件清不掉
find /home/user/.cache -type f -name "*" -delete
# ✅ 正确:明确包含隐藏文件
find /home/user/.cache -type f \( -name "*" -o -name ".*" \) -delete
坑 11:软链接用相对路径,链接一挪就失效
bash
# ❌ 错误:相对路径以链接所在位置为基准
ln -s ../data/config.yaml /home/user/link.yaml
# ✅ 正确:用绝对路径
ln -s /data/config.yaml /home/user/link.yaml
坑 12:kill 不是立即生效
bash
# ❌ 错误:kill 完没确认
kill -9 12345
# ✅ 正确:先 TERM 优雅退出,5 秒后没死再 KILL,最后确认
kill 12345
sleep 5
kill -9 12345 2>/dev/null
ps -p 12345 || echo "进程已退出"
二十八、发行版差异与命令对照表
Linux 发行版千千万,但万变不离其宗:内核一样,命令大同小异,差异集中在包管理、服务管理和个别命令名。掌握对照表,任何发行版都能秒上手。
28.1 主流发行版家族
渲染错误: Mermaid 渲染失败: Lexical error on line 10. Unrecognized text. ...SUSE] D1 -. 包格式 .deb / 包管理 apt .-> P ----------------------^
28.2 包管理对照表
| 操作 | Debian/Ubuntu | CentOS/Rocky | Fedora | Arch | openSUSE |
|---|---|---|---|---|---|
| 软件包格式 | .deb |
.rpm |
.rpm |
.pkg.tar.zst |
.rpm |
| 更新索引 | apt update |
yum makecache |
dnf makecache |
pacman -Sy |
zypper refresh |
| 安装软件 | apt install nginx |
yum install nginx |
dnf install nginx |
pacman -S nginx |
zypper install nginx |
| 删除软件 | apt remove nginx |
yum remove nginx |
dnf remove nginx |
pacman -R nginx |
zypper remove nginx |
| 搜索软件 | apt search nginx |
yum search nginx |
dnf search nginx |
pacman -Ss nginx |
zypper search nginx |
| 升级全部 | apt upgrade |
yum update |
dnf upgrade |
pacman -Syu |
zypper update |
| 清理缓存 | apt clean |
yum clean all |
dnf clean all |
pacman -Scc |
zypper clean |
注意:CentOS 7 用
yum,CentOS 8+/Rocky/Alma 用dnf(yum只是dnf的兼容别名)。
28.3 命令新旧对照表(老命令 vs 现代替代)
| 老命令 | 现代替代 | 说明 |
|---|---|---|
ifconfig |
ip addr |
查看网卡 IP |
route -n |
ip route |
查看路由 |
netstat -tlnp |
ss -tlnp |
查看端口监听 |
arp -a |
ip neigh |
查看邻居表 |
service nginx start |
systemctl start nginx |
启动服务 |
chkconfig nginx on |
systemctl enable nginx |
开机自启 |
iptables -L |
firewall-cmd --list-all |
查看防火墙规则(RHEL 系) |
uptime(看负载) |
uptime |
未变,仍是最快看负载的方式 |
28.4 服务管理:SysVinit → systemd
现代发行版几乎全部使用 systemd,核心命令统一:
bash
systemctl start nginx # 启动
systemctl stop nginx # 停止
systemctl restart nginx # 重启
systemctl reload nginx # 平滑重载配置(不中断服务,nginx 等支持)
systemctl status nginx # 查看状态
systemctl enable nginx # 开机自启
systemctl disable nginx # 取消自启
systemctl list-units --type=service --state=running # 列出运行中的服务
journalctl -u nginx -f # 查看服务日志(配合 systemd 使用)
老系统(SysVinit)对照 :service nginx start ≈ systemctl start nginx;chkconfig nginx on ≈ systemctl enable nginx。
28.5 从 CentOS 7 迁移到 Rocky/Alma(或 Ubuntu)速查
CentOS 7 已停止维护(2024-06),迁移时命令对照:
| 场景 | CentOS 7(旧) | Rocky/Alma 9(新) | Ubuntu 22.04+(新) |
|---|---|---|---|
| 安装 | yum install vim |
dnf install vim |
apt install vim |
| 防火墙 | firewall-cmd --zone=public --add-port=80/tcp --permanent |
同左(RHEL 系一致) | ufw allow 80/tcp |
| SELinux 查看 | getenforce |
同左 | 无 SELinux(AppArmor) |
| 查看版本 | cat /etc/redhat-release |
cat /etc/os-release |
cat /etc/os-release |
迁移三个最容易踩的坑:
- yum → dnf:命令兼容,但仓库源(repo)要换;
- 防火墙配置:CentOS 7 的 firewalld 规则在 Rocky/Alma 通用,Ubuntu 则完全不同(ufw);
- SELinux 状态 :RHEL 系默认 Enforcing,nginx 等自定义端口可能被拦截,排查时先
getenforce。
28.6 本章小结
记住三句话:
- 判断发行版:
cat /etc/os-release; - 装软件前先确认包管理器(
apt/dnf/pacman/zypper); - 现代系统服务管理一律
systemctl+journalctl,老命令对照表查本文 28.3。