Linux命令行合集(涵盖定时任务、防火墙、SHH、线上问题实战等)

Linux 命令全家桶:28 章 200+ 命令实战速查(附面试考点 · 踩坑指南 · 发行版对照)

这是一份能直接照着敲 的 Linux 命令实战手册:28 章、200+ 命令、100+ 代码示例 。从入门(文件 / 目录 / 权限)到进阶(文本三剑客、进程网络、防火墙 SSH),再到文件系统原理、网络抓包、面试考点、踩坑锦集、发行版对照------日常开发、运维排障、求职面试一册搞定。
适合人群:Linux 初学者 / 后端与运维工程师 / 备战面试的同学

读完你将获得

  1. 200+ 常用命令的直接复用手册,附 30 条速查表
  2. 16 个高频面试考点速答,直接背答案
  3. 12 个新手易踩的坑与正确姿势,少走弯路
  4. 五大发行版(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 抓包、发行版对照、面试考点

先看一张全章知识脑图,心里有张地图再上路(点击图片可查看高清大图):


目录

命令入门

文件与目录操作

文本处理

权限与用户

进程与系统

  • 十一、进程管理与后台运行
  • [十二、系统服务:systemctl 管理](#十二、系统服务:systemctl 管理)
  • [十三、定时任务:cron 与 at](#十三、定时任务:cron 与 at)

网络、安全与系统

  • 十四、网络诊断与请求
  • [十五、防火墙命令:ufw / firewalld / iptables](#十五、防火墙命令:ufw / firewalld / iptables)
  • [十六、SSH 远程连接与文件传输](#十六、SSH 远程连接与文件传输)
  • [十七、日志查看:journalctl 与系统日志](#十七、日志查看:journalctl 与系统日志)
  • 十八、磁盘与内存监控
  • [十九、压缩打包:tar 与 zip](#十九、压缩打包:tar 与 zip)

软件与综合

原理进阶与面试避坑

  • [二十四、文件系统与 inode:理解 Linux 如何存储文件](#二十四、文件系统与 inode:理解 Linux 如何存储文件)
  • [二十五、网络抓包与连接排查:tcpdump / ss / lsof / ip](#二十五、网络抓包与连接排查:tcpdump / ss / lsof / ip)
  • 二十六、高频面试考点速答
  • [二十七、踩坑锦集:新手最容易犯的 12 个错误](#二十七、踩坑锦集:新手最容易犯的 12 个错误)
  • 二十八、发行版差异与命令对照表

一、Linux 命令基础:打开终端的第一步

1.1 命令的基本格式

Linux 命令的统一格式是:

bash 复制代码
命令名 [选项] [参数]
  • 命令名 :要执行的程序,如 lscdcat
  • 选项 :修饰命令行为,短选项用单个 -(如 -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 eth0ip addr show eth0route -nip routearp -aip neigh

25.2 ss:端口与连接状态一网打尽

ssnetstat 的现代替代,更快更准(生产环境优先用 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:findgrep 的区别?

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%CPUload 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 -Icurl -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 -hdf -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),你的 python3node 可能根本不在 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 用 dnfyum 只是 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 startsystemctl start nginxchkconfig nginx onsystemctl 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

迁移三个最容易踩的坑

  1. yum → dnf:命令兼容,但仓库源(repo)要换;
  2. 防火墙配置:CentOS 7 的 firewalld 规则在 Rocky/Alma 通用,Ubuntu 则完全不同(ufw);
  3. SELinux 状态 :RHEL 系默认 Enforcing,nginx 等自定义端口可能被拦截,排查时先 getenforce

28.6 本章小结

记住三句话

  1. 判断发行版:cat /etc/os-release
  2. 装软件前先确认包管理器(apt / dnf / pacman / zypper);
  3. 现代系统服务管理一律 systemctl + journalctl,老命令对照表查本文 28.3。
相关推荐
张洛闻Eren8 小时前
MySQL 维护稳定系统【MySQL第二课】
linux·数据库·mysql·云原生
ltl8 小时前
Linux 异步 I/O:epoll 与 io_uring 对比
linux
ltl8 小时前
压缩算法工程实践:吞吐、比率与 CPU 权衡
linux
fiveym9 小时前
01 - iPXE + Clonezilla 网络装机原理解析
linux·运维·服务器·网络
虎头金猫9 小时前
如何在群晖NAS上通过Docker部署CloudSaver?群晖部署CloudSaver教程|聚合资源搜索并实现远程访问
运维·服务器·网络·python·docker·容器·pandas
反转180度10 小时前
Qt 6 + C++17 实现 SFTP 批量部署:工业设备运维工具实战解析
运维·c++·qt
雨辰AI11 小时前
RAG 知识库搭建:基于人大金仓构建信创运维问答机器人|全栈国产化落地完整版
运维·ai·机器人·ai编程
-今昭-11 小时前
Ansible
linux·运维·ansible