# 第02讲：Linux操作系统目录结构与文件操作

> **本节目标**：理解Linux系统的起源与设计哲学，掌握目录组织方式和常用文件操作命令，为后续系统编程打下基础

## 前置知识
- [[01_系统运行机制]] -- 对操作系统的基本认识
- 计算机基本操作能力

---

## 一、UNIX/Linux系统简介

### 1.1 UNIX的诞生

1969年，贝尔实验室（Bell Labs）的 **Ken Thompson** 和 **Dennis Ritchie** 在一台废弃的PDP-7小型机上开发了UNIX操作系统。此后Ritchie还创造了C语言，并用C语言重写了UNIX，使UNIX成为第一个用高级语言编写的操作系统，极大地提高了可移植性。

```mermaid
graph LR
    A["1969 Ken Thompson
Dennis Ritchie"] -->|在PDP-7上开发| B[UNIX初版]
    B -->|用C语言重写| C[UNIX V6/V7]
    C -->|研究方向| D[BSD UNIX]
    C -->|商业方向| E[System V]
    D --> F[FreeBSD / NetBSD]
    E --> G[AIX / Solaris / HP-UX]

    style A fill:#fff3e0
    style C fill:#e1f5fe
```

### 1.2 UNIX两大流派

| 流派 | 代表 | 特点 |
|------|------|------|
| **BSD UNIX**（研究版） | BSD 4.x | 由加州大学伯克利分校维护，偏重学术研究 |
| **System V**（商业版） | SVR4 | 由AT&T维护，偏重商业应用 |

### 1.3 主要商业UNIX版本

| 版本 | 厂商 | 典型硬件平台 |
|------|------|-------------|
| **AIX** | IBM | Power/PowerPC |
| **Solaris** | Sun Microsystems | SPARC / x86 |
| **HP-UX** | HP | PA-RISC / Itanium |
| **IRIX** | SGI | MIPS |

---

## 二、Linux系统

### 2.1 Linux的诞生

1991年，芬兰赫尔辛基大学的学生 **林纳斯·托瓦兹（Linus Torvalds）** 开发了Linux内核。最初这只是个人项目，但由于他将内核源码以GPL（GNU General Public License）协议发布，全球开发者得以自由修改和分发，Linux迅速成长为最重要的开源操作系统。

### 2.2 内核版本号

Linux内核版本号的格式为 **`r.x.y`**：

- **r**（主版本号）：内核有重大变更时递增
- **x**（次版本号）：偶数表示稳定版，奇数表示开发版
- **y**（修订版本号）：bug修复和小改动

常见内核版本线：2.4 -> 2.6 -> 3.2 -> 4.6.4 -> 5.x -> 6.x

> **注意**：从3.0开始，主版本号不再有"奇偶"含义，版本号只是简单的递增计数器。

### 2.3 Linux发行版

内核本身只是操作系统的核心部分。**发行版（Distribution）** 将内核与各种工具、桌面环境、软件包管理器等打包在一起，形成完整的操作系统。

```mermaid
graph TB
    A[Linux内核] --> B[GNU工具集]
    B --> C[发行版]
    C --> D[RHEL]
    C --> E[Fedora]
    C --> F[Ubuntu]
    C --> G[CentOS]
    C --> H[中标麒麟]

    style A fill:#ffcdd2
    style C fill:#e1f5fe
```

| 发行版 | 特点 | 典型用途 |
|--------|------|---------|
| **RHEL**（Red Hat Enterprise Linux） | 商业支持，稳定 | 企业服务器 |
| **Fedora** | 技术前沿，更新快 | 桌面 / 开发 |
| **Ubuntu** | 用户友好，社区活跃 | 桌面 / 云服务器 |
| **CentOS** | RHEL的免费克隆版 | 企业服务器 |
| **中标麒麟** | 国产化，政府认证 | 国内政府 / 国防 |

---

## 三、Linux目录结构

### 3.1 核心概念：一切皆文件

与Windows不同，Linux **没有盘符**（C:、D:等）的概念。整个文件系统从根目录 **`/`** 开始，形成一棵倒置的树。

```mermaid
graph TB
    ROOT["/ (根目录)"] --> BIN["/bin
基本命令"]
    ROOT --> SBIN["/sbin
系统管理命令"]
    ROOT --> ETC["/etc
配置文件"]
    ROOT --> HOME["/home
用户家目录"]
    ROOT --> VAR["/var
可变数据"]
    ROOT --> USR["/usr
用户程序"]
    ROOT --> TMP["/tmp
临时文件"]
    ROOT --> DEV["/dev
设备文件"]
    ROOT --> PROC["/proc
进程信息"]
    ROOT --> BOOT["/boot
内核与启动"]
    ROOT --> LIB["/lib
共享库"]
    ROOT --> MNT["/mnt
挂载点"]
    ROOT --> OPT["/opt
第三方软件"]
    ROOT --> ROOT2["/root
root用户家目录"]

    style ROOT fill:#ffcdd2
    style ETC fill:#fff3e0
    style HOME fill:#e8f5e9
    style PROC fill:#e1f5fe
    style DEV fill:#f3e5f5
```

### 3.2 重要目录详解

| 目录 | 全称 | 作用 | 举例 |
|------|------|------|------|
| `/bin` | Binaries | 基本用户命令 | `ls`, `cp`, `cat` |
| `/sbin` | System Binaries | 系统管理命令 | `fdisk`, `ifconfig` |
| `/etc` | Editable Text Config | 系统配置文件 | `/etc/passwd`, `/etc/fstab` |
| `/home` | Home | 普通用户家目录 | `/home/zhangsan` |
| `/root` | Root Home | root用户的家目录 | -- |
| `/var` | Variable | 可变数据（日志、缓存等） | `/var/log/messages` |
| `/usr` | Unix System Resources | 用户程序和数据 | `/usr/bin`, `/usr/lib` |
| `/tmp` | Temporary | 临时文件，重启后可能清除 | -- |
| `/dev` | Device | 设备文件 | `/dev/sda`（硬盘） |
| `/proc` | Process | 虚拟文件系统，内核运行信息 | `/proc/cpuinfo` |
| `/boot` | Boot | 启动相关文件（内核镜像等） | `vmlinuz-xxx` |
| `/lib` | Library | 共享库文件 | `libc.so.6` |
| `/mnt` | Mount | 临时挂载点 | U盘、网络存储 |

### 3.3 /proc文件系统

`/proc` 是一个 **虚拟文件系统** -- 它不占用磁盘空间，而是内核在内存中动态生成的。通过读取 `/proc` 下的文件，可以实时查看系统和进程信息。

```bash
# 查看CPU信息
cat /proc/cpuinfo

# 查看内存信息
cat /proc/meminfo

# 查看当前进程信息（PID=1的进程）
cat /proc/1/status
```

---

## 四、目录操作命令

### 4.1 特殊目录符号

| 符号 | 含义 | 示例 |
|------|------|------|
| `.` | 当前目录 | `./program`（运行当前目录下的程序） |
| `..` | 上一级目录 | `cd ..`（回到上级目录） |
| `~` | 当前用户的家目录 | `cd ~`（回到家目录） |
| `-` | 上一次所在的目录 | `cd -`（在两个目录间来回切换） |

### 4.2 常用目录操作命令

```bash
# pwd - 显示当前工作目录（Print Working Directory）
pwd
# 输出：/home/zhangsan

# cd - 切换目录（Change Directory）
cd /usr/local       # 绝对路径切换
cd ..               # 回到上级目录
cd ~                # 回到家目录（等同于 cd $HOME）
cd -                # 回到上一次的目录

# mkdir - 创建目录（Make Directory）
mkdir mydir                # 创建单个目录
mkdir -p project/src/main  # 递归创建多级目录

# rmdir - 删除空目录（Remove Directory）
rmdir mydir                # 只能删除空目录

# rm - 删除文件或目录
rm file.txt                # 删除文件
rm -r mydir                # 递归删除目录及其内容
rm -ri mydir               # 递归删除，每个文件都询问确认
```

---

## 五、文件操作命令

### 5.1 查看文件内容

```bash
# ls - 列出目录内容（List）
ls                 # 列出当前目录下的文件
ls -l              # 长格式显示（含权限、大小、时间）
ls -a              # 显示隐藏文件（以 . 开头的文件）
ls -lh             # 长格式 + 人类可读的文件大小

# cat - 连接并显示文件内容
cat file.txt       # 显示文件全部内容
cat -n file.txt    # 显示时带行号

# more / less - 分页查看
more file.txt      # 空格翻页，q 退出
less file.txt      # 更强大的分页器，支持搜索
```

### 5.2 复制、移动和重命名

```bash
# cp - 复制文件或目录（Copy）
cp file1.txt file2.txt         # 复制文件
cp -r dir1/ dir2/              # 递归复制目录
cp -i file1.txt file2.txt      # 覆盖前询问

# mv - 移动/重命名（Move）
mv file.txt /tmp/              # 移动文件到 /tmp
mv oldname.txt newname.txt     # 重命名
```

### 5.3 文件权限管理

每个文件都有三组权限，分别针对三类用户：

| 权限位 | 含义 | 对文件的效果 | 对目录的效果 |
|--------|------|-------------|-------------|
| **r**（读） | Read | 可以查看文件内容 | 可以列出目录内容 |
| **w**（写） | Write | 可以修改文件内容 | 可以在目录中创建/删除文件 |
| **x**（执行） | Execute | 可以运行文件 | 可以进入目录（`cd`） |

三类用户：
- **u**（user/所有者）：文件的拥有者
- **g**（group/所属组）：与文件同组的用户
- **o**（others/其他人）：其余所有用户

```bash
# chmod - 修改文件权限（Change Mode）
chmod u+x program.sh     # 给所有者添加执行权限
chmod g-w file.txt       # 去掉组的写权限
chmod 755 program.sh     # 数字表示法：rwxr-xr-x
chmod 644 data.txt       # 数字表示法：rw-r--r--

# chown - 修改文件所有者（Change Owner）
chown zhangsan file.txt           # 修改所有者
chown zhangsan:staff file.txt    # 同时修改所有者和所属组
chown -R zhangsan:staff mydir/   # 递归修改目录
```

**权限的数字表示法**：

| 数字 | 二进制 | 权限 |
|------|--------|------|
| 7 | 111 | rwx |
| 6 | 110 | rw- |
| 5 | 101 | r-x |
| 4 | 100 | r-- |
| 0 | 000 | --- |

因此 `chmod 755` 等价于 `rwxr-xr-x`：所有者可读可写可执行，组和其他人可读可执行。

---

## 六、绝对路径与相对路径

### 6.1 概念对比

| 路径类型 | 起点 | 示例 | 特点 |
|----------|------|------|------|
| **绝对路径** | 根目录 `/` | `/home/zhangsan/file.txt` | 完整路径，从根开始，与当前位置无关 |
| **相对路径** | 当前目录 | `./file.txt` 或 `../dir/file.txt` | 相对于当前位置，更短更灵活 |

### 6.2 示例

假设当前目录为 `/home/zhangsan/project`：

```bash
# 绝对路径方式
cat /home/zhangsan/project/src/main.c

# 相对路径方式（效果相同）
cat ./src/main.c
cat src/main.c

# 使用 .. 回到上级
cat ../README.md     # 访问上级目录中的 README.md
```

```mermaid
graph TB
    HOME["/home"] --> ZS["zhangsan"]
    ZS --> PROJ["project"]
    PROJ --> SRC["src"]
    SRC --> MAIN["main.c"]
    ZS --> README["README.md"]

    PROJ -.->|"cd .."| ZS
    PROJ -.->|"cd ./src"| SRC
    PROJ -.->|"cat ../README.md"| README

    style PROJ fill:#fff3e0
    style MAIN fill:#e8f5e9
```

---

## 七、知识关联

- Linux的"一切皆文件"思想在 [[04_文件IO编程]] 中会深入学习
- 文件权限在 [[04_文件IO编程]] 中用 `open()` 系统调用的 `mode` 参数体现
- `/proc` 文件系统在 [[05_进程控制]] 中用于查看进程状态
- 后续C语言编程需要在Linux环境下进行，参见 [[03_C语言编程基础]]

---

## 八、思考题

1. **为什么Linux没有盘符？** 这种设计有什么优势？
2. **/proc 为什么是"虚拟"文件系统？** 它与 /home 这样的目录有什么本质区别？
3. **`rm -rf /` 会发生什么？** 为什么root用户执行这个命令非常危险？
4. **`chmod 755` 和 `chmod 644` 分别适用于什么场景？**（提示：可执行文件 vs 数据文件）

---

## 九、扩展阅读

- 《鸟哥的Linux私房菜》第5-6章：Linux文件权限与目录配置
- 《UNIX环境高级编程》第1-2章：UNIX基础知识
- Linux文件系统层次标准（FHS）：https://pathname.com/fhs/
