Linux核心知识点全解01
Linux 核心知识点全解:从 Shell 到内核,一篇带你彻底搞懂
本文基于运维实战中的高频问题清单整理而成,覆盖 Shell、Linux 服务、用户管理、命令体系、文件权限、内核机制六大板块。每个核心概念都配有 图解,语言通俗,适合入门和进阶复盘。
目录
一、Shell 核心知识点
1.1 什么是 Shell
通俗来说,Shell 就是你跟操作系统之间的"翻译官"。你在黑乎乎的终端里敲下的每一条命令,都不是直接发给操作系统内核的——内核根本看不懂人类写的 ls、cd 这种文字。Shell 负责把你说的话翻译成内核能懂的语言,再把内核的回应翻译回来给你看。
flowchart LR
A[用户 👤] -->|"输入命令 (ls / cd / mkdir)"| B[Shell 命令解释器]
B -->|"翻译为系统调用 (syscall)"| C[操作系统内核 Kernel]
C -->|"操作"| D[硬件资源]
D -->|"返回结果"| C
C -->|"原始数据"| B
B -->|"格式化输出"| A
Shell 在操作系统中的角色可以总结为三点:
| 角色 | 说明 |
|---|---|
| 命令解释器 | 接收用户输入的命令文本,解析语法,翻译成系统调用 |
| 编程环境 | 提供变量、循环、分支、函数等编程能力,可编写脚本批量执行 |
| 进程调度器 | 管理前台/后台进程,处理进程间的通信与信号 |
Shell 命令解释器的工作原理
当你敲下 ls -l /home 并按下回车时,Shell 内部经历了下面这些步骤:
flowchart TD
A["用户输入: ls -l /home"] --> B[读取输入]
B --> C[词法分析: 拆分为 token]
C --> D["token: [ls, -l, /home]"]
D --> E{是内置命令?}
E -->|是| F[直接执行内置功能]
E -->|否| G[在 PATH 路径中查找可执行文件]
G --> H{找到?}
H -->|否| I["报错: command not found"]
H -->|是| J[fork 创建子进程]
J --> K[exec 替换子进程为 ls 程序]
K --> L[子进程执行完毕, 返回状态码]
L --> M[Shell 收到状态码, 继续等待下一条命令]
简单说,Shell 做四件事:读 → 拆 → 找 → 跑,然后循环往复,这就是所谓的 REPL(Read-Eval-Print Loop)。
1.2 Shell 的种类与选择
Shell 不是只有一种,就像一个操作系统上可以有多种浏览器一样。以下是四种最常见的 Shell:
mindmap
root((Shell 家族))
Bourne Shell 系
sh - 最原始的 Bourne Shell
bash - Bourne Again Shell
默认在大多数 Linux 发行版
兼容 sh,功能更丰富
zsh - Z Shell
兼容 bash
强大的自动补全和主题插件
Oh My Zsh 生态
ksh - Korn Shell
商业 Unix 常用
C Shell 系
csh - C Shell
语法类似 C 语言
tcsh - TENEX C Shell
csh 的增强版
命令行编辑更友好
fish - Friendly Interactive Shell
开箱即用,无需配置
语法不兼容 bash
适合交互式使用
| Shell | 特点 | 适合人群 |
|---|---|---|
| bash | Linux 标配,兼容性最好,脚本生态最强 | 运维工程师、后端开发 |
| zsh | 自动补全强大,主题丰富,Oh My Zsh 生态 | 前端/全栈开发者、追求效率的人 |
| fish | 开箱即用,智能提示,语法现代化 | 新手、不想折腾配置的人 |
| tcsh | C 语言风格语法,历史悠久的 BSD 默认 Shell | 老派 Unix 用户 |
日常如何选择?
- 写脚本 → 用 bash(兼容性第一)
- 日常敲命令 → 用 zsh 或 fish(体验好)
- 服务器运维 → 用 bash(所有服务器都有)
1.3 Shell 脚本详解
什么是 Shell 脚本?核心作用是什么?
Shell 脚本就是把一堆 Shell 命令写进一个文件里,让它按顺序自动执行。与其每次手动敲 20 条命令,不如写一个脚本一次跑完。
核心作用: 自动化——把重复的人工操作变成一段可复用的程序。
主要使用场景
flowchart LR
subgraph 使用场景
A[系统管理]
B[日志分析]
C[批量处理]
D[定时任务]
E[环境部署]
F[监控告警]
end
A -->|"用户管理、磁盘清理、备份"| S((Shell 脚本))
B -->|"grep/awk/sed 日志统计"| S
C -->|"批量重命名、批量转换"| S
D -->|"crontab 定时执行"| S
E -->|"一键安装、服务启停"| S
F -->|"进程监控、资源告警"| S
分支、循环、函数的作用
# 分支:根据不同条件执行不同操作
if [ -f "/etc/nginx/nginx.conf" ]; then
echo "nginx 已安装"
else
echo "nginx 未安装,开始安装..."
apt install nginx -y
fi
# 循环:对一组数据重复执行相同操作
for user in alice bob charlie; do
useradd $user # 批量创建用户
echo "用户 $user 创建完成"
done
# 函数:封装可复用的代码块
function check_service() {
local svc=$1
if systemctl is-active --quiet $svc; then
echo "$svc 运行中 ✅"
else
echo "$svc 已停止 ❌"
fi
}
check_service nginx
check_service mysql
| 结构 | 核心作用 |
|---|---|
| 分支 (if/case) | 根据条件决定执行哪段代码,实现"按需执行" |
| 循环 (for/while) | 对批量数据逐一遍历,实现"批量操作" |
| 函数 (function) | 封装可复用逻辑,避免重复代码,便于维护 |
Shell 脚本的优缺点
| 优点 | 缺点 |
|---|---|
| 编写快,一行命令就是一个功能 | 没有完善的调试工具,排错靠 echo 和 set -x |
| 几乎任何 Linux 环境都能跑,零依赖 | 复杂逻辑写起来很痛苦,代码可读性差 |
| 调用系统命令极其方便 | 性能差,不适合计算密集型任务 |
| 非常适合"胶水"任务(串联各种工具) | 缺乏现代语言特性(类型检查、面向对象等) |
适合的场景: 系统运维、日志处理、环境部署、定时任务、CI/CD 脚本 不适合的场景: 大型项目开发、复杂算法、网络服务、需跨平台的应用
二、Linux 服务核心知识点
2.1 什么是 Linux 服务?服务的本质是什么?
服务 = 一个在后台长期运行的进程,专门对外提供某种功能。比如 Web 服务器 Nginx 就是一个服务,它一直在后台等着处理 HTTP 请求。
服务的本质: 其实就是一个被特别管理的进程。被谁管?被服务管理器(如 systemd)管——它负责服务的启动、停止、重启、开机自启等。
2.2 什么是守护进程(Daemon)?
守护进程是运行在后台、不与任何终端关联的进程。名字来源于希腊神话中的"守护精灵",默默地在背后干活。
flowchart TD
subgraph "普通进程 vs 守护进程"
A[普通进程] --> A1[绑定终端]
A --> A2[关闭终端则进程退出]
A --> A3[有标准输入/输出]
B[守护进程 Daemon] --> B1[脱离终端]
B --> B2[关闭终端不影响运行]
B --> B3[输入输出重定向到日志文件]
end
服务和守护进程的关系: 大多数 Linux 服务的运行形态就是守护进程。可以说:服务是概念层,Daemon 是实现层。比如 sshd 既是一个守护进程,也是 SSH 服务的运行实例。
2.3 服务管理机制对比:systemd vs init vs upstart
timeline
title Linux 服务管理演进史
section SysV init 时代
1983 : 最早的 init 系统
: 串行启动,速度慢
: 用 /etc/init.d/ 脚本管理
section Upstart 时代
2006 : Ubuntu 推出 Upstart
: 支持事件驱动
: 兼容 init 脚本
section systemd 时代
2010 : systemd 诞生
: 并行启动,速度快
: 成为主流标准
| 特性 | SysV init | Upstart | systemd |
|---|---|---|---|
| 启动方式 | 串行(一个接一个) | 事件驱动 | 并行启动 |
| 配置文件 | Shell 脚本 /etc/init.d/ | /etc/init/*.conf | 单元文件 /etc/systemd/system/ |
| 依赖管理 | 靠编号顺序,手动控制 | 支持事件依赖 | 强大的依赖关系定义 |
| 启动速度 | 慢 | 较快 | 快 |
| 当前状态 | 已被淘汰 | 基本被淘汰 | 主流标准 |
2.4 服务与进程的关系
flowchart LR
subgraph 进程视角
P1[进程1: PID 1000]
P2[进程2: PID 1001]
P3[进程3: PID 1002]
end
subgraph 服务视角
S1[nginx.service] -.->|"管理"| P1
S2[mysql.service] -.->|"管理"| P2
S3[sshd.service] -.->|"管理"| P3
end
SM[服务管理器 systemd] --> S1
SM --> S2
SM --> S3
- 进程是操作系统层面的概念——一段正在运行的程序,有 PID、内存空间、CPU 时间片
- 服务是管理层面的概念——systemd 把某个进程(或进程组)包装成一个可管理的单元,可以
start/stop/restart/enable - 一个服务不一定只对应一个进程(如 Nginx 会 fork 出多个 worker 进程)
- 一个进程中也可以承载多个服务的功能(较少见)
三、Linux 用户管理知识点
3.1 用户分类
flowchart TD
RU[Linux 用户体系] --> A[超级用户 root]
RU --> B[系统用户]
RU --> C[普通用户]
A --> A1["UID = 0"]
A --> A2["拥有最高权限,无所不能"]
A --> A3["一般禁止直接登录,改用 sudo"]
B --> B1["UID 通常 1~999"]
B --> B2["为系统服务创建,如 www-data, mysql"]
B --> B3["不能登录系统"]
C --> C1["UID 通常 >= 1000"]
C --> C2["日常登录使用的用户"]
C --> C3["权限受限制,仅能操作自己的文件"]
| 用户类型 | UID 范围 | 用途 | 能否登录 |
|---|---|---|---|
| root | 0 | 系统超级管理员 | 一般禁止 |
| 系统用户 | 1 ~ 999(CentOS 7 之前)/ 1 ~ 999 | 运行特定服务 | 否 |
| 普通用户 | 1000 ~ 60000+ | 日常使用 | 是 |
3.2 UID 和 GID
在 Linux 眼里,它不认识"张三""李四"这种用户名,它只认数字。 UID(User ID)就是用户的数字身份证,GID(Group ID)是用户组的数字身份证。用户名只是给人类看的别名。
flowchart LR
H[人类视角] -->|"用户名: alice"| T[翻译层 /etc/passwd]
T -->|"UID: 1000"| M[机器视角 内核]
H2[人类视角] -->|"用户组: developers"| T2[翻译层 /etc/group]
T2 -->|"GID: 1001"| M
用户和用户组的管理逻辑:
- 每个用户必须属于一个主组(Primary Group)
- 一个用户可以属于多个附加组(Supplementary Groups)
- 文件归属同时记录
UID和GID,权限检查时先匹配 UID,再匹配 GID
3.3 用户管理核心命令
| 命令 | 功能 | 示例 |
|---|---|---|
useradd | 创建用户 | useradd -m -s /bin/bash alice |
usermod | 修改用户属性 | usermod -aG docker alice |
userdel | 删除用户 | userdel -r alice |
passwd | 设置/修改密码 | passwd alice |
groupadd | 创建用户组 | groupadd developers |
groupmod | 修改用户组 | groupmod -n newname oldname |
groupdel | 删除用户组 | groupdel developers |
id | 查看用户 UID/GID | id alice |
su | 切换用户 | su - alice |
sudo | 以 root 身份执行命令 | sudo apt update |
四、Linux 命令与核心设计理念
4.1 什么是 Linux 命令?命令的本质是什么?
一条 Linux 命令,本质上就是一个可执行程序文件,存放在文件系统的某个目录里。当你敲下 ls,Shell 会在 /bin、/usr/bin 等路径下找到一个叫 ls 的二进制文件然后运行它。
4.2 命令的完整解析过程
flowchart TD
A["$ ls -l /home 2>&1 | grep alice > result.txt"] --> B["1. 解析引号和转义"]
B --> C["2. 拆分为管道: cmd1 | cmd2"]
C --> D["cmd1: ls -l /home 2>&1"]
C --> E["cmd2: grep alice > result.txt"]
D --> F["3. 继续拆分: 命令=ls, 参数=-l /home"]
F --> G["4. 处理重定向: 2>&1(标准错误合并到标准输出)"]
E --> H["3. 继续拆分: 命令=grep, 参数=alice"]
H --> I["4. 处理重定向: > result.txt(输出写入文件)"]
G --> J["5. 查找命令位置: /bin/ls"]
I --> K["5. 查找命令位置: /bin/grep"]
J --> L["6. fork 子进程执行"]
K --> M["6. fork 子进程执行"]
L --> N["7. 标准输出通过管道传给下一个进程"]
N --> M
关键机制: 管道(|)、重定向(>、<、>>、2>&1)、变量替换($VAR)、命令替换($(cmd))、通配符展开(*、?)——这些都是在命令真正执行之前由 Shell 先处理的。
4.3 「一切皆文件」核心理念
这是 Linux 最灵魂的设计思想。通俗地说:Linux 把几乎所有东西都抽象成了"文件" 。不管你是读一块硬盘,还是读一个键盘输入,还是读一个网络数据包,在 Linux 看来,你都是在"读文件"。
flowchart TD
LF["一切皆文件 Everything is a File"] --> A[普通文件: 文本、图片、视频]
LF --> B[目录文件: 文件夹]
LF --> C[设备文件: /dev/sda 硬盘, /dev/tty 终端]
LF --> D[特殊文件]
D --> D1[/proc/cpuinfo: CPU信息/]
D --> D2[/proc/meminfo: 内存信息/]
D --> D3[/dev/null: 黑洞,丢弃所有数据/]
D --> D4[/dev/zero: 无限0字节流/]
D --> D5[/dev/random: 随机数/]
LF --> E[管道文件: 进程间通信]
LF --> F[Socket文件: 网络通信]
LF --> G[软链接 / 硬链接]
一个直观的例子:
# 读硬盘和读普通文件用的是同一个系统调用
cat /home/user/hello.txt # 读普通文件
cat /dev/sda # 读整块硬盘!看作"文件"
# 读系统信息也是"读文件"
cat /proc/cpuinfo # 查看 CPU 信息
cat /proc/meminfo # 查看内存信息
# 写设备也是"写文件"
echo "hello" > /dev/tty1 # 在第一个终端上显示 "hello"
这样设计的目的和优势
| 优势 | 说明 |
|---|---|
| 统一的编程接口 | 无论操作什么,都用 open()、read()、write()、close() 这个套路 |
| 简化开发 | 写程序的不用区分"这是硬盘还是网卡",统一按文件处理 |
| 强大的组合能力 | 不同"文件"之间可以通过管道串联,实现复杂的处理流程 |
| 权限统一管理 | 万物皆文件→万物都有 rwx 权限,安全模型统一 |
五、Linux 文件权限知识点
5.1 权限基础概念
Linux 权限 = 这道门的钥匙,控制谁能对这个文件做什么操作。权限机制是 Linux 安全体系的第一道防线。
flowchart LR
subgraph "三类角色"
U[文件所有者 Owner]
G[所属组 Group]
O[其他人 Others]
end
subgraph "三种权限"
R[r: 读 Read]
W[w: 写 Write]
X[x: 执行 eXecute]
end
U --> R
U --> W
U --> X
G --> R
G --> W
G --> X
O --> R
O --> W
O --> X
5.2 rwx 权限对文件和目录的区别
这是 Linux 权限中最容易搞混的地方,也是面试最爱问的。
| 权限 | 作用于普通文件 | 作用于目录文件 |
|---|---|---|
| r (读) | 可以查看文件内容(cat、less) | 可以列出目录中的文件名(ls) |
| w (写) | 可以修改文件内容(vim、echo >>) | 可以在目录中创建/删除/重命名文件 |
| x (执行) | 可以作为程序运行(./script.sh) | 可以进入该目录(cd),可以访问目录内文件 |
flowchart TD
subgraph "目录权限的微妙之处"
A["目录 /data 权限: rwxr--r--"] --> B{"用户 alice 不是 owner 也不在组里"}
B --> C["有 r 权限:可以 ls 看到文件名"]
C --> D["没有 x 权限:不能 cd 进入"]
D --> E["没有 x 权限:不能访问 /data 下的任何文件"]
E --> F["即使 /data/file.txt 的权限是 777,也无法读取!"]
end
关键结论: 对一个目录来说,x(执行)权限是访问目录的"通行证" 。没有 x 权限,连门都进不去,更别提读里面的文件了。
5.3 看懂 ls -l 输出
$ ls -l /etc/passwd
-rw-r--r-- 1 root root 2860 May 22 10:30 /etc/passwd
flowchart LR
A["-rw-r--r--"] --> A1["文件类型: - 普通文件<br>d 目录 / l 软链接 / c 字符设备 / b 块设备"]
A --> A2["Owner 权限: rw-"]
A --> A3["Group 权限: r--"]
A --> A4["Others 权限: r--"]
B["1"] --> B1["硬链接数"]
C["root"] --> C1["文件所有者"]
D["root"] --> D1["所属组"]
E["2860"] --> E1["文件大小(字节)"]
F["May 22 10:30"] --> F1["最后修改时间"]
G["/etc/passwd"] --> G1["文件名"]
5.4 修改权限的常用方式
| 方式 | 格式 | 示例 | 说明 |
|---|---|---|---|
| 符号法 | chmod [ugoa][+-=][rwx] | chmod u+x script.sh | 给 owner 加执行权限 |
chmod g-w file.txt | 去掉 group 的写权限 | ||
chmod o=r file.txt | 设置 others 仅有读权限 | ||
chmod a+r file.txt | 所有人加读权限 | ||
| 数字法 | chmod [0-7][0-7][0-7] | chmod 755 script.sh | rwxr-xr-x |
chmod 644 file.txt | rw-r--r-- | ||
chmod 600 secret.key | rw------- | ||
| 改归属 | chown / chgrp | chown alice file.txt | 改所有者 |
chown alice:dev file.txt | 同时改所有者和组 |
数字法速记表:
| 数字 | 二进制 | 权限 |
|---|---|---|
| 0 | 000 | --- |
| 1 | 001 | --x |
| 2 | 010 | -w- |
| 3 | 011 | -wx |
| 4 | 100 | r-- |
| 5 | 101 | r-x |
| 6 | 110 | rw- |
| 7 | 111 | rwx |
六、Linux 内核核心知识点
6.1 什么是 Linux 内核?它在操作系统中的核心地位是什么?
内核就是操作系统的"大脑" ——它直接跟硬件打交道,管理 CPU、内存、硬盘、网络等一切物理资源,为上层应用程序提供一个安全、稳定的运行环境。
flowchart TD
subgraph "用户空间 User Space"
APP[应用程序 App]
LIB[标准库 libc]
SHELL[Shell]
end
subgraph "内核空间 Kernel Space"
direction TB
SYSCALL[系统调用接口]
PM[进程管理]
MM[内存管理]
FS[文件系统]
NET[网络协议栈]
DD[设备驱动]
end
subgraph "硬件层 Hardware"
CPU[CPU]
RAM[内存]
DISK[硬盘]
NIC[网卡]
end
APP --> LIB
LIB --> SYSCALL
SHELL --> SYSCALL
SYSCALL --> PM
SYSCALL --> MM
SYSCALL --> FS
SYSCALL --> NET
PM --> CPU
MM --> RAM
FS --> DISK
NET --> NIC
DD --> DISK
DD --> NIC
一句话总结: 用户程序不能直接碰硬件,必须通过内核中转。内核是唯一的"硬件管家"。
6.2 内核的核心功能
| 功能模块 | 做什么 |
|---|---|
| 进程管理 | 创建/销毁进程,CPU 时间片调度,多任务管理 |
| 内存管理 | 分配/回收内存,虚拟内存,内存映射 |
| 文件系统 | 管理磁盘数据,提供统一的 VFS(虚拟文件系统) |
| 网络协议栈 | 实现 TCP/IP 协议,管理网络连接 |
| 设备驱动 | 和各类硬件设备通信,提供统一的操作接口 |
| 安全机制 | 权限检查、访问控制、SELinux/AppArmor |
6.3 内核空间与用户空间
flowchart TD
subgraph "用户空间 (Ring 3)"
direction LR
UA[应用程序 A]
UB[应用程序 B]
UC[应用程序 C]
end
subgraph "内核空间 (Ring 0)"
KM[内核代码 & 数据]
end
subgraph "硬件"
HW[CPU / 内存 / 硬盘 / 网卡]
end
UA <-.->|"系统调用 (受控门)"| KM
UB <-.->|"系统调用 (受控门)"| KM
UC <-.->|"系统调用 (受控门)"| KM
KM -->|"直接访问"| HW
UA -.-|"禁止直接访问"| HW
为什么要隔离?—— 两个字:安全。
- 内核空间(Ring 0) :拥有最高权限(内核态),可以访问所有内存和硬件
- 用户空间(Ring 3) :权限受限(用户态),只能访问自己被分配的内存区域
- 应用程序想操作硬件 → 必须通过系统调用(syscall)向内核"申请"
- 内核检查请求是否合法 → 合法才执行 → 把结果返回给应用程序
这样就保证了:即使应用程序崩溃或恶意操作,也不会搞崩整个系统,更不会偷窥其他进程的数据。
扩展: 内核态和用户态的切换是有成本的(上下文切换),这就是为什么高性能应用要尽量减少系统调用次数。
6.4 常见内核类型
| 内核类型 | 特征 | 代表系统 |
|---|---|---|
| 单内核(Monolithic) | 所有功能都在一大块内核里,效率高但耦合度高 | Linux、Unix |
| 微内核(Microkernel) | 内核只保留最核心的功能,其他放用户空间,更安全但性能较低 | Minix、QNX |
| 混合内核(Hybrid) | 单内核 + 微内核的折中方案 | Windows NT、macOS |
Linux 是典型的单内核,但它支持动态加载/卸载内核模块(insmod / rmmod),走了一条兼顾扩展性的路线。
6.5 日常运维中如何查看内核信息
# 查看内核版本
uname -r # 输出示例: 5.15.0-91-generic
uname -a # 完整系统信息
# 查看内核详细信息
cat /proc/version # 内核版本 + 编译信息
# 查看已加载的内核模块
lsmod # 列表形式
# 查看某个模块的详细信息
modinfo ext4 # 查看 ext4 模块信息
# 查看内核启动参数
cat /proc/cmdline
# 查看内核编译配置(如果存在)
cat /boot/config-$(uname -r)
# 查看内核日志(dmesg)
dmesg | tail -50 # 最近50条内核消息
dmesg | grep -i error # 查找错误信息
dmesg | grep -i memory # 查找内存相关信息
总结
本文围绕六组核心知识点,从概念到原理、从图表到实操,系统地梳理了 Linux 基础知识的骨架:
- Shell —— 用户与系统的"翻译官",既是命令解释器也是编程环境
- 服务 —— 由 systemd 管理的后台进程,系统功能的运行载体
- 用户管理 —— UID/GID 是核心,三类用户各司其职
- 命令体系 —— 本质是可执行文件,管道和重定向是灵魂
- 文件权限 —— rwx 三权分立,文件和目录权限含义大不同
- 内核 —— 操作系统的大脑,用户空间与内核空间隔离保证安全
希望能帮助你建立对 Linux 系统完整、清晰的理解框架。
本文基于运维实战知识清单整理编写,持续更新中。--- 小黑蛋