↑ 顶部/笔记 2026-10-25 · 约 11 分钟

系统构成与 Shell

一句话总结:内核管硬件、Shell 管命令——Linux 启动的每一步、你敲的每条命令,都能在这套结构里找到位置。
环境:Rocky Linux / CentOS 9,bash。

更新于 2026-10-25 · 正文约 4239 字

一、Linux 系统构成(功能维度)

操作系统从运行空间上大致分为内核空间和用户空间。用户空间跑应用和系统库,内核空间跑内核。两者之间通过系统调用接口交互:应用通过系统库发起系统调用,CPU 从用户态切换到内核态,内核处理请求——可能是操作硬件,也可能是管理进程、内存、文件系统等——处理完再返回用户态。用户态和内核态是 CPU 的特权级状态,系统调用、中断、异常是进入内核态的入口。

从功能上看,系统分成两大部分:

部分 职责 举例
内核(kernel) 和下层硬件打交道:进程调度、内存管理、文件系统、网络协议栈、设备驱动 分配 CPU 时间片、把文件读到内存
系统调用接口(syscall) 和上层应用程序打交道:给程序提供“请求内核干活”的入口 open()、read()、write()、fork()

由此产生两个“态”:

用户态和内核态是 CPU 的两种特权级别,不是接口。
用户态运行应用,内核态运行内核和驱动。
系统调用接口是用户态进入内核的通道。
硬件由内核态管理,应用通过系统调用请求内核服务。

状态 运行什么代码 权限 说明
用户态(user mode) 应用程序、Shell、系统调用接口代码 受限,不能直接碰硬件 你敲的命令绝大多数在这里跑
内核态(kernel mode) 内核代码 最高权限 只有陷入内核(系统调用、中断)才进入

一次 cat /etc/passwd 的路径:bash(用户态)→ open()/read() 系统调用 → 内核态读磁盘 → 把数据拷回用户态 → 打印。

二、文件维度:bootfs 与 rootfs

操作系统来自 ISO 镜像,里面是一堆系统文件,分两大类:

组成 阶段 内容
bootfs 系统启动前 bootloader 程序(写在硬盘第一个扇区 MBR,512B)、内核文件 vmlinuz、initramfs
rootfs 系统启动后 本质就是一堆文件夹和文件:/etc、/usr、/var……

BIOS 固定只找第一个扇区;后续文件怎么找,是 bootloader 的事。

三、进程与程序

概念 定义 特点
程序 一个或一系列代码文件 静态,躺在硬盘上
进程 程序运行的过程 动态,占用 CPU、内存、文件描述符

操作系统把硬盘里的程序读进内存,再让 CPU 执行指令,程序才“跑起来”变成进程。

进程是操作系统最核心的概念——CPU 调度、内存分配、权限控制,全是围着进程转的。

ps aux          # 看所有进程
ps -ef | grep sshd
top             # 动态看资源占用
kill -9 PID     # 强杀

四、启动流程(BIOS → 内核 → systemd)

加电
 └─> BIOS/UEFI 自检,找启动盘(固定读第一个扇区)
      └─> MBR/GPT 里的 bootloader(GRUB2)
           └─> 加载内核 vmlinuz + initramfs 到内存
                └─> 内核初始化硬件、挂载根文件系统
                     └─> 启动第一个用户态进程 systemd(PID 1)
                          └─> 按 default.target 拉起各项服务

进程的“族谱”:

PID 进程 作用
0 swapper / idle 内核创建的调度进程,空闲时占着 CPU
1 systemd(旧版 init) 所有用户态进程的祖先,管服务、管挂载、管登录
2 kthreadd 所有内核线程的祖先
pstree -p | head        # 看进程树
ps -p 1 -o pid,comm     # 确认 1 号进程

五、运行级别与 target

运行级别 systemd target 含义
0 poweroff.target 关机
1 rescue.target 单用户救援
2 multi-user.target 多用户,无 NFS
3 multi-user.target 字符终端(默认,进入 bash)
4 — 未使用
5 graphical.target 图形界面(需装桌面)
6 reboot.target 重启
systemctl get-default                        # 查看默认
systemctl set-default multi-user.target      # 永久切字符界面
systemctl set-default graphical.target       # 永久切图形界面
init 3 / init 5 / init 0 / init 6            # 临时切换(老写法)
yum -y group install "Server with GUI"       # 装图形桌面

六、Shell 是什么

Shell = 命令解释器,翻译成“壳”,表达了对系统调用封装的思想:你在壳里敲命令,它替你去调内核。

  • 启动级别为 3 时,系统登录后给你一个铺满屏幕的字符终端,里面跑的就是 shell。
  • 常见种类:bash(默认)、sh、zsh、ksh、csh。
  • 查看当前 shell:echo $SHELL、ps -p $$。

配置文件(登录时读哪些):

文件 作用
/etc/profile 全局,登录 shell 读
/etc/bashrc 全局,每次开 bash 读
~/.bash_profile 用户级,登录时读(常会再 source ~/.bashrc)
~/.bashrc 用户级,每次开新 shell 读,别名一般写这里
~/.bash_logout 退出时执行
source ~/.bashrc     # 改完立即生效,等价于 . ~/.bashrc

七、命令的三段式与查找优先级

ls -l /boot
│  │  └── 参数:操作目标
│  └───── 选项:控制怎么做(可省略)
└──────── 命令:做什么

同一个名字可能有很多来源,bash 按固定顺序找:

顺序 类型 例子 说明
0 带 / 的路径 /bin/ls、./a.sh 指名道姓,直接执行,不查其他
1 别名 alias alias ll='ls -l' 最先展开
2 函数 function myfunc(){ ... } shell 函数
3 内建命令 builtin cd、echo、type bash 自带,不需要外部文件
4 哈希缓存 hash hash 之前找到过的外部命令路径缓存
5 PATH 里的外部命令 /usr/bin/ls 从左到右找目录
6 找不到 — command not found
type ls          # 看它到底是什么:别名/内建/文件
type -a ls       # 所有可能来源
which ls         # 只找 PATH 里的可执行文件
whereis ls
hash -r          # 清空哈希缓存(换了新版本命令后常用)

八、各种“命令”的写法

# 别名:临时生效,写进 ~/.bashrc 才永久
alias ll='ls -lh'
unalias ll

# 函数
f() { echo 111; echo 222; }
f

# 复合命令
for ((i=0;i<3;i++)); do echo 66666; done

# 内建命令
type cd pwd type

九、bash 快捷键与历史

快捷键 作用
Ctrl+C 强制终止当前命令
Ctrl+L 清屏(等于 clear)
Ctrl+A / Ctrl+E 光标跳到行首 / 行尾
Ctrl+U / Ctrl+K 删到行首 / 删到行尾
Ctrl+R 反向搜索历史命令
↑ ↓ 翻历史命令
Tab 补全命令/路径(按两次列出候选)
history          # 带编号的历史
!123             # 执行第 123 条
!!               # 上一条命令
!$               # 上一条命令的最后一个参数
history -c       # 清空历史

十、环境变量与 PATH

环境变量是进程运行环境的配置字典:路径、语言、代理、编辑器参数都靠它,让程序不改代码就能适配环境。

命令 作用
env / set 查看环境变量 / 所有变量
echo $PATH 查看 PATH
export NAME=value 定义并导出,对当前进程及子进程生效
unset NAME 删除变量
export PATH="$PATH:$HOME/bin"   # 让 shell 额外去 ~/bin 找命令
echo $PATH                      # 冒号分隔的一堆目录

永久生效:写进 ~/.bashrc(用户)或 /etc/profile.d/xxx.sh(全局)。

十一、Shell 脚本入门

脚本 = 把完成某个任务的一串命令放进一个文件。

#!/bin/bash
# 第一行 shebang 指定解释器
echo "hello"
ls -l /tmp
chmod +x mmm      # 赋予执行权限
./mmm             # 用相对路径执行

想让 mmm 在任何目录都能直接敲,两种办法:

  1. 把脚本放进 PATH 里的某个目录(如 ~/bin、/usr/local/bin);
  2. 把脚本所在目录加进 PATH。

十二、常用系统命令

命令 作用 例子
hostname / hostnamectl 查看 / 永久设置主机名 hostnamectl set-hostname test
date 时间 date "+%F %T"、date -s "2024-04-15 11:11:11"
timedatectl 时区 / NTP timedatectl set-timezone Asia/Shanghai
ip a / ifconfig 看网卡和 IP ip a show ens33
nmcli NetworkManager nmcli conn up ens33
shutdown 关机/重启 shutdown -h +10、shutdown -c
reboot / init 6 重启
uname -a 内核与架构 uname -m、uname -r
cat /etc/redhat-release 系统版本
man ls / ls --help 帮助

集群里时间一致非常重要:所有机器都向 NTP 服务器对时(chronyd)。生产环境时间漂移会导致日志对不上、证书校验失败、数据库主从异常。

速查表

systemctl get-default
systemctl set-default multi-user.target
hostnamectl set-hostname test
ip a; nmcli conn up ens33
date "+%F %T"; timedatectl
uname -a; cat /etc/redhat-release
type -a ls; which ls; hash -r
alias ll='ls -lh'; unalias ll
export PATH="$PATH:$HOME/bin"
echo $SHELL; ps -p $$
history | tail; !$
systemctl status sshd; systemctl restart sshd

常见坑

  1. alias 只在当前 shell 有效,想永久必须写进 ~/.bashrc 再 source。
  2. 改 ~/.bashrc 后不 source,新开窗口才生效。
  3. ./script.sh 和 script.sh 不一样:不带 ./ 会去 PATH 里找。
  4. 脚本没有 chmod +x 就执行会报 Permission denied。
  5. export 只影响当前进程及其子进程,不影响父进程。
  6. 误改 PATH 导致命令全找不到时,用绝对路径 /bin/ls 先救急,再改回配置。
  7. history -c 清空后,~/.bash_history 里可能还留着(退出时才写入)。

练习(15 题)

先自己做,再点开答案核对 0 / 15 已查看

01

内核和系统调用接口分别负责和谁打交道?

查看答案

系统调用接口负责和上层应用程序打交道,内核负责和下层硬件打交道。

02

用户态和内核态最本质的区别是什么?

查看答案

用户态代码权限受限、不能直接操作硬件,只能通过系统调用请求内核;内核态拥有最高权限,可以直接访问硬件和所有内存。

03

bootfs 和 rootfs 各包含什么?

查看答案

bootfs 在系统启动前使用,包含 bootloader、内核 vmlinuz、initramfs;rootfs 是启动后挂载的根文件系统,就是 /etc、/usr、/var 这些目录和文件。

04

写出 Linux 从加电到 systemd 启动的主要步骤。

查看答案

加电 → BIOS/UEFI 自检并找启动盘 → 读取第一个扇区的 bootloader(GRUB2)→ 加载内核和 initramfs → 内核初始化硬件并挂载根文件系统 → 启动 systemd(PID 1)→ 按 default.target 拉起服务。

05

PID 1 和 PID 2 分别是什么进程,各自负责什么?

查看答案

PID 1 是 systemd(旧系统是 init),所有用户态进程的祖先,负责服务管理、挂载、登录;PID 2 是 kthreadd,所有内核线程的祖先。PID 0 是内核的 swapper/idle 进程。

06

把系统默认启动方式永久改成字符终端,写出命令。

查看答案
systemctl set-default multi-user.target
07

查看当前系统默认 target 和上次启动耗时。

查看答案
systemctl get-default
systemd-analyze

systemd-analyze 还能看到内核、initrd、用户空间各阶段耗时。

08

当前 shell 是哪种?用什么命令查看?

查看答案
echo $SHELL
ps -p $$

$SHELL 是登录 shell 的路径,$$ 是当前 shell 的 PID。

09

一条命令同时显示 ls 是别名、函数还是外部命令。

查看答案
type -a ls

它会按别名、函数、内建、PATH 的顺序全部列出来。

10

清除 bash 的命令哈希缓存,写命令并说明为什么要清。

查看答案
hash -r

哈希缓存记录了命令的绝对路径;换了新版本、改了 PATH 或删了旧命令后,缓存会导致仍执行旧路径,需要清掉。

11

!$ 和 !! 分别代表什么?

查看答案

!! 执行上一条命令;!$ 取上一条命令的最后一个参数,例如上一条是 ls /etc,cat !$ 就等于 cat /etc。

12

把 ~/bin 加入 PATH,并且只对当前会话生效。

查看答案
export PATH="$PATH:$HOME/bin"

只影响当前 shell 和它的子进程,关掉窗口就失效。

13

写一个最简单的 shell 脚本并让它能执行。

查看答案
cat > ~/hello.sh <<'EOF'
#!/bin/bash
echo "hello"
EOF
chmod +x ~/hello.sh
~/hello.sh
14

查看主机名、系统版本、内核版本,各一条命令。

查看答案
hostname
cat /etc/redhat-release
uname -r
15

集群为什么必须保证时间一致?用什么服务对时?

查看答案

时间不一致会让日志对不上、证书校验失败、数据库主从复制异常、定时任务错乱。用 chronyd(NTP 客户端)向时间服务器同步,timedatectl set-ntp yes 开启。

系统构成与 Shell · 生成于 2026-10-26 00:46