写在前面

前面的学习内容主要集中在 C 语言、数据结构、51 单片机以及一些底层原理上。从这一篇开始,我准备正式开启一个新的系列:

Linux 系统编程。

这里的目标并不是单纯学习几个 Linux 命令,也不是把 Linux 当作“另一个桌面操作系统”来使用,而是逐步建立对操作系统、Linux 进程、文件系统、权限、编译链接、系统调用、进程通信、网络编程这些内容的完整认识。

在真正开始敲命令之前,我觉得有一个问题必须先搞明白:

Linux 到底是什么?它和 UNIX、macOS、iOS 又是什么关系?

因为如果这些概念一开始就混在一起,后面很容易出现:

Linux 是 UNIX 吗?
macOS 是 Linux 吗?
Android 为什么又和 Linux 有关系?
Ubuntu、CentOS、Debian 到底又是什么?

这一篇就先把这些背景知识理清楚。


一、从UNIX到Linux:渊源与定位

1.1 一切的起点:UNIX

Linux 的出现并不是凭空发生的。如果要理解 Linux,最自然的起点其实是 UNIX

20 世纪 60 年代末,贝尔实验室的 Ken Thompson、Dennis Ritchie 等人在此前大型操作系统研究的基础上,逐渐开发出了 UNIX。早期 UNIX 有几个非常重要的特点:多用户、多任务、文件系统设计简洁、大量功能可以通过小程序组合完成、很多系统能力最终都表现为统一的文件接口。

后来 UNIX 不断发展,并逐渐形成了不同分支,其中比较有影响力的两条路线是:

                 UNIX
                  │
        ┌─────────┴─────────┐
        │                   │
      AT&T                BSD
        │                   │
   System V          Berkeley UNIX

BSD,也就是 Berkeley Software Distribution,对后来的网络协议栈、操作系统设计影响非常大,尤其是 TCP/IP 网络的发展,与 BSD UNIX 有非常深的历史联系。所以今天我们学习 socket、TCP/IP、进程、文件描述符、权限、shell 这些东西时,会不断看到 UNIX 留下来的设计思想。

1.2 Linux 与 UNIX 的关系

这是最容易混淆的地方。一句话先下结论:

Linux 不是 UNIX 源代码直接发展出来的 UNIX 系统,而是按照 UNIX 思想重新实现出来的 Unix-like 系统。

Linux 官方内核资料本身就将 Linux 描述为一个从头编写的 Unix clone,并强调它朝着 POSIX 和 Single UNIX Specification 兼容方向发展。这意味着:

UNIX
  ↓
形成了一套非常成熟的操作系统设计思想和接口习惯
  ↓
Linux 学习并重新实现这些思想

但是 Linux ≠ UNIX源码复制版

更准确地说:Linux 与 UNIX 有很深的思想继承关系,但 Linux 内核是 Linus Torvalds 在 1991 年开始独立开发的,Linux 内核项目自 1991 年开始发展,后来逐渐成为世界上规模最大的自由软件项目之一。

因此可以理解成:

UNIX
   │
   ├── 各类传统 UNIX
   │
   └── 设计思想 / 标准 / 接口
             │
             ↓
          Linux
      独立重新实现

1.3 什么是“类 UNIX”系统

因为 Linux 在很多核心设计上都和 UNIX 非常接近,例如:

一切皆文件的设计思想
文件描述符
进程模型
权限系统
Shell
管道
重定向
POSIX接口
目录结构
网络接口

所以学习 Linux 系统编程时,经常会看到 Unix-like,也就是“类 UNIX 系统”。

这里需要区分两个概念:

  • UNIX:更多指一个有明确历史来源、标准体系以及商标认证意义的操作系统家族。
  • Unix-like:表示“行为、接口、设计思想很像 UNIX”。

Linux 就属于典型 Unix-like 系统。

1.4 macOS、iOS 与 Linux 是什么关系

macOS 不是 Linux,这点一定要先记住。它们大致可以这样理解:

                UNIX 世界
                   │
        ┌──────────┴──────────┐
        │                     │
 BSD / UNIX路线          Linux路线
        │                     │
      Darwin              Linux Kernel
        │                     │
      macOS              Ubuntu / Debian
                           RHEL / CentOS
                           Arch ...

macOS 的底层建立在 Darwin 体系上。Apple 的 XNU 内核由 Mach、BSD 组件、IOKit 等部分组合构成,Apple 的公开资料也明确说明 XNU 用于 Darwin,并服务于 macOS 和 iOS。

所以:macOS 和 Linux 并不是“谁基于谁”的关系,它们更像是都处在 UNIX / Unix-like 技术世界里,但走的是不同路线。而且 macOS 的部分版本通过了 The Open Group 的 UNIX 03 认证,例如 macOS 15 Sequoia 就在其 UNIX 03 注册产品列表中。因此,说 macOS 与 UNIX 有直接血缘和标准关系,是成立的。

而 iOS 和 macOS 的关系反而更近。它们底层都使用 Apple 的 Darwin / XNU 技术体系,所以可以粗略理解:

            Darwin / XNU
               │
        ┌──────┴──────┐
        │             │
      macOS          iOS

但这里也要避免一个说法:“iOS 就是 UNIX”。更准确的说法是:iOS 与 macOS 共享大量 Darwin/XNU 底层技术,属于 Unix-like 技术体系;但不能简单把 iOS 和通过 UNIX 认证的 macOS 完全等同起来。

所以我们可以得到一个很清晰的关系:

Linux:Unix-like,Linux内核独立实现
macOS:Darwin/XNU路线,并有UNIX认证版本
iOS:同样基于Darwin/XNU技术体系
Android:基于Linux内核

这几个名字以后不要再混在一起。


二、Linux生态:内核、开源与发行版

2.1 “Linux”到底指什么?

日常交流里我们经常说“我装了一个Linux”,但严格来说:

Linux 本身首先指的是 Linux Kernel,也就是 Linux 内核。

kernel.org 也特别提醒:如果普通用户只是想“安装 Linux”,真正需要的是一个完整的 Linux distribution,而不只是下载内核源码。

一个完整可用的操作系统,还需要很多东西:

Linux Kernel
    +
GNU工具
    +
Shell
    +
系统库
    +
软件包管理器
    +
桌面环境(可选)
    +
各种应用程序

最后才形成 Linux 发行版

所以可以理解成:

Linux内核
   │
   ├── Debian
   │    └── Ubuntu
   │
   ├── RHEL
   │    └── CentOS体系
   │
   ├── Fedora
   │
   ├── Arch
   │
   └── ...

2.2 开源到底是什么意思

Linux 最重要的特点之一就是开放源代码。Linux 内核采用 GNU GPL v2 许可证,kernel.org 的 FAQ 也明确说明 Linux kernel 在 GPLv2 条款下发布。

但“开源”绝不仅仅意味着“源代码能看”,更重要的是:

你可以阅读
你可以学习
你可以修改
你可以重新编译
你可以参与开发
你可以发布符合许可证要求的衍生版本

这直接改变了软件发展的方式。

这里也要澄清一个常见误区:开源 ≠ 免费,闭源 ≠ 一定收费。真正核心的区别是:源代码是否开放,以及用户获得了什么使用、修改和再发布权利。

可以简单对比:

维度开源软件闭源软件
源代码通常公开通常不公开
修改取决于许可证,一般允许一般不允许
二次发布按许可证执行通常受到严格限制
开发模式社区/企业共同参与较多公司内部开发较多
可审计性较高外部通常无法查看实现
商业化完全可以完全可以

所以开源和商业化并不冲突,Red Hat、Canonical 等公司的很多业务,本身就是建立在开源生态上的。

2.3 什么是Linux发行版

Linux 内核只有核心能力。真正让普通用户可以直接安装、使用的,是各种 Linux Distribution。

不同发行版会组合 Linux 内核、GNU 工具、系统库、包管理器、安装程序、桌面环境、软件仓库、默认配置。所以:

发行版不是不同的“Linux内核品牌”,而是围绕 Linux 内核构建的完整操作系统方案。

2.4 常见的Linux发行版

Debian

Debian 是非常重要的社区发行版之一,特点是稳定、社区驱动、软件包体系成熟。Ubuntu 就是在 Debian 基础上发展起来的,Ubuntu 官方文档也直接称 Debian 是 Ubuntu 的基础。

Ubuntu

Ubuntu 是目前学习 Linux 时非常常见的一种发行版。它基于 Debian,使用 APT、.deb 软件包体系。后面的 Linux 系列里,我也会主要使用 Ubuntu 作为其中一个学习环境。

Red Hat / RHEL

RHEL 即 Red Hat Enterprise Linux,偏向企业级场景。它非常强调稳定性、长期支持、企业服务、认证体系,很多传统企业 Linux 运维内容都和 Red Hat 生态关系很深。

CentOS

以前很多课程把 CentOS 当作“免费的 RHEL 重构版”来教学。这里需要补一个现在非常重要的变化:

传统 CentOS Linux 已经结束生命周期。

CentOS 官方显示,CentOS Linux 7 已于 2024 年 6 月 30 日结束生命周期;目前 CentOS 项目的重点已经转向 CentOS Stream

所以我后面如果说“使用 CentOS 学习”,会明确区分旧课程中的 CentOS Linux 和当前 CentOS Stream,不会把两者完全混为一谈。如果为了和学校课程、教材环境保持一致,我可能仍然会接触旧 CentOS 命令与配置;但实际建立新环境时,会优先考虑 CentOS Stream / Ubuntu 等仍在维护的系统。

2.5 为什么同时接触Ubuntu和CentOS系

这是因为它们正好代表两种非常典型的生态:

  • Ubuntu / Debian 系:常见 aptapt installdpkg
  • RHEL / CentOS 系:常见 dnfyumrpm

很多 Linux 基础知识其实完全一样,比如 cdlspwdmkdircpmvrmchmodpskillgccmakessh。真正差异比较明显的地方主要在软件包管理、系统配置、发行版默认行为、软件版本、服务管理细节。所以同时接触两边,对理解 Linux 发行版差异很有帮助。


三、为什么我们要学Linux:系统编程与服务器场景

3.1 为什么Linux适合学习系统编程

因为在 Linux 上,很多操作系统机制并没有被厚厚的图形界面完全隐藏起来。例如进程、线程、文件描述符、管道、信号、内存、网络、权限、动态链接,都可以非常直接地观察和操作。

学习 fork()exec()open()read()write()pipe()socket() 这些接口时,我们实际上是在接近:操作系统真正提供给应用程序的能力。

这也是我后面学习 Linux 的重点,不是为了“会用Linux桌面”,而是为了逐渐理解:

程序到底怎样运行
操作系统到底怎样管理资源
用户代码怎样进入内核
进程之间怎样通信
网络程序怎样工作

3.2 为什么服务器端Linux更主流

桌面环境里,大多数普通用户首先接触的往往是 Windows、macOS。而到了服务器、云计算、容器、嵌入式领域,Linux 的存在感会明显增强。

原因并不是一句“因为 Linux 免费”这么简单,更重要的是:

  • 可定制;
  • 自动化能力强;
  • SSH 远程管理成熟;
  • 软件生态完善;
  • 容器、云计算生态成熟;
  • 源代码开放;
  • 易于裁剪;
  • 对大量硬件架构支持完善。

Linux 内核已经从最早的 x86 PC 平台扩展到大量不同处理器架构,并被用于桌面、服务器、嵌入式设备乃至超级计算机等场景。所以以后真正接触云服务器、Docker、Kubernetes、Nginx、MySQL、Redis、Git服务、CI/CD 时,会发现 Linux 几乎绕不开。

3.3 为什么更推荐命令行学习

刚接触 Linux 的时候,很容易觉得“有桌面为什么不用桌面?”因为桌面确实更直观。但系统开发和服务器场景更强调 Shell、SSH、命令行、脚本,原因非常现实。

服务器通常没有必要运行完整GUI

图形桌面需要显存、内存、CPU、大量图形组件,而服务器更希望资源真正给 Web、数据库、计算任务、业务服务。

命令行适合远程管理

只需要 ssh user@server 就能管理远程服务器,不需要远程传输整个桌面画面。

命令可以自动化

例如 gcc main.c -o main./main 这些东西可以手动执行、写进Shell脚本、写进Makefile、写进CI/CD。图形界面的鼠标点击则很难批量自动化。

命令行更接近系统本身

学习 Linux 系统编程,本来就是为了逐渐进入操作系统内部。所以:命令行不是“落后的操作方式”,而是系统开发中的重要接口。


四、学习路线:C、Linux与C++的衔接规划

4.1 操作系统的层次定位

在真正进入 Linux 命令以前,还需要建立一个最基本的层次结构:

┌──────────────────┐
│    用户应用程序   │
│ gcc / vim / nginx│
├──────────────────┤
│   系统库 / Shell │
├──────────────────┤
│   Linux Kernel   │
├──────────────────┤
│       硬件       │
│CPU/内存/磁盘/网卡 │
└──────────────────┘

操作系统的一个核心价值就是:管理硬件资源,并向上层程序提供统一、可靠的接口。

例如一个普通程序并不会直接自己控制磁盘磁头、内存芯片、网卡寄存器、CPU调度,而是告诉操作系统:我要读文件、我要写文件、我要创建进程、我要申请内存、我要发送网络数据,操作系统再统一管理这些资源。

4.2 从C语言到Linux系统编程

这也是我为什么会在学完一段 C 语言和数据结构之后,再开始 Linux。因为 Linux 系统编程和 C 语言的联系非常紧密,后面会大量出现 intchar*void*structpointermallocfreefunction pointer,以及 open()read()write()fork()exec()wait()pipe()

如果 C 语言基础不牢,系统编程会非常吃力。但反过来:学 Linux 系统编程也会让我重新理解很多以前学过的 C 语言知识。例如文件指针、文件描述符、进程地址空间、动态内存、函数调用、编译链接、静态库、动态库,以前是从“语言”角度看,后面则会从操作系统角度重新看一遍。

4.3 数据结构进阶:为什么转向C++

Linux 系列开始以后,我还会再继续写几篇当前阶段的 C 语言数据结构内容,把现在正在学习的部分收尾。但更进阶的数据结构和算法,我准备逐渐放到 C++ 系列 中继续。

原因不是“C 语言不能实现高级数据结构”,事实上当然可以。但是随着数据结构越来越复杂,比如二叉搜索树、AVL树、红黑树、哈希表、图、各种容器,如果始终只使用 C,就需要不断自己处理类型、内存、泛型问题、重复接口、资源释放、容器封装,很多时间会逐渐花在“重复造轮子”,而不是算法本身。

C++ 可以提供 template、class、RAII,以及 std::vectorstd::stringstd::stackstd::queuestd::mapstd::unordered_map。我们仍然可以自己实现数据结构,但不用每次都重新解决所有外围问题。

例如以后实现 AVL、红黑树、图算法、并查集、优先队列、哈希结构,用 C++ 可以更加集中精力研究算法结构、复杂度、泛型设计、接口设计,而不是让大量篇幅消耗在底层重复管理上。

所以路线不是“学了C++以后不用C”,而是:

C
↓
理解底层、内存、指针、系统接口

C++
↓
继续数据结构、算法与更大规模工程

两者并不冲突。

4.4 后续整体学习路线

目前准备把几个方向并行推进。

Linux 系列

从这篇背景介绍开始,后面逐渐进入 Linux常用命令、文件和目录、权限、vim、gcc / g++、make / Makefile、进程、线程、文件IO、进程间通信、网络。环境方面主要会接触 Ubuntu + CentOS 系,其中涉及 CentOS 时,会区分旧 CentOS Linux 教学环境和当前 CentOS Stream。

C 数据结构系列

还会继续完成目前正在学的内容,把 C 语言数据结构阶段尽量形成一个完整闭环。

C++ 系列

之前已经写过 C++ 相关内容,后面会继续推进。更进阶的数据结构内容,也会逐渐迁移到 C++ 中。

所以后面的整体路线大概是:

              C语言基础
                  │
       ┌──────────┴──────────┐
       │                     │
  Linux系统编程          C数据结构收尾
       │                     │
       │                     ↓
       │                 C++数据结构
       │                     │
       └──────────┬──────────┘
                  ↓
          更完整的软件开发

这也比一直停留在单一语言或者单一数据结构上更符合后面的学习需求。


写在最后

Linux 是一个很容易“越学越大”的领域。刚开始可能只是 lscdpwd 几个命令,但往后会逐渐连接到 C 语言、操作系统、计算机网络、编译原理、数据结构、数据库、服务器、云计算、嵌入式。

所以这一篇没有急着开始背 Linux 命令,而是先把最容易混淆的几组关系理清楚:

UNIX ≠ Linux
Linux 是 Unix-like 系统的独立实现
Linux 严格来说首先指内核
Ubuntu / CentOS / Debian 是 Linux 发行版
macOS 走 Darwin / XNU / BSD 路线
iOS 与 macOS 共享 Darwin / XNU 技术体系
Android 则建立在 Linux 内核之上

Linux 最重要的特点之一,则是它背后的开放源代码开发模式。从最初由 Linus Torvalds 开始开发的内核,到今天能够运行在大量硬件和应用场景中,Linux 的发展本身就是开源协作模式非常典型的案例。Linux kernel 至今仍是持续高速发展的自由软件项目。

下一篇就不再停留在历史背景上了,接下来会真正进入 Linux 环境,从远程登录、Shell、目录结构与常用基础命令开始,逐渐建立 Linux 系统编程的操作基础。而这一整个 Linux 系列,我也会和 C/C++、数据结构一起继续推进,而不是完全割裂开来。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐