
1. Unix是什么先把这套操作系统的来龙去脉理清楚我第一次登上一台生产服务器其实是被逼的。当时项目组里没人愿意碰那台跑着数据库的机器我硬着头皮敲下第一个ls看到满屏目录的时候脑子是空的。后来才明白我面对的不是什么神秘黑框而是一套有几十年历史、被无数人打磨过的操作系统家族Linux 只是它最重要的一个分支。这篇是 Linux 基础篇的第一讲我想把 Unix/Linux 操作系统本身讲透——它从哪来、内核里到底装了什么、发行版为什么有那么多版本、新手第一次装系统该怎么下手。不管你是刚摸到命令行的学生还是写过几年代码但对底层一直含糊的开发者这一篇都能帮你把地基打牢。很多教程一上来就让你背命令我倒觉得顺序反了。你连自己敲的命令最终落到内核哪个子系统上都说不清背再多也是死记。所以咱们先不着急敲键盘先搞清楚这套系统是怎么长出来的它的设计取舍是什么后面学起来会顺很多。1.1 从Multics的失败说起Unix其实是个“副产品”时间拨回上世纪六十年代末。当时贝尔实验室、麻省理工和通用电气三家联手做一个叫 Multics 的项目目标是造一个功能极其完备的分时操作系统能让很多用户同时用一台大型机。这个愿景很宏大但工程复杂度失控了开发进度一拖再拖投入巨大却看不到尽头贝尔实验室最终在 1969 年选择退出。退出之后有位工程师肯·汤普森想继续玩自己写的一个太空飞行游戏可当时机器资源紧张他就找了一台被闲置的 PDP-7 小型机用汇编语言从头写了一套精简的操作系统来支撑这个游戏。这套系统比 Multics 简单太多同事布莱恩·柯林汉半开玩笑地把它叫做 Unics取“单路信息与计算服务”之意跟 Multics 的“多路”形成对照后来拼写慢慢演变成了 Unix。你看一个影响半个世纪的技术起点竟然是想玩游戏这事儿特别有意思也说明好的技术往往是从解决具体问题里长出来的不是规划出来的。1.2 三条设计哲学决定了Unix家族的性格Unix 能活这么久靠的不是功能多而是一套被反复验证的设计原则。我梳理下来最核心的三条理解了它们你后面看 Linux 的一切设计都会觉得顺理成章。第一是一切皆文件。在 Unix 里普通文本、硬盘、键盘、网络套接字、甚至进程信息都被抽象成文件来读写。这样做的好处是接口统一你学会open、read、write、close这几个操作就能对付几乎所有设备。新手常觉得/dev/sda这种名字很怪其实它就是一个代表硬盘的设备文件。第二是每个工具只做一件事并且做好。ls就负责列目录grep就负责过滤文本sort就负责排序它们各自简单但通过管道可以串起来。这就是为什么你在命令行里能写出ps aux | grep nginx | awk {print $2}这种组合拳它不是某个大程序的功能而是几个小工具拼出来的。第三是用纯文本作为通用接口。配置文件是文本、日志是文本、命令输出也是文本谁都能读、能改、能 grep。这种朴素的选择让系统可组合、可脚本化也是 Shell 脚本至今仍然好用的根本原因。1.3 Unix家族的分裂以及POSIX标准的意义Unix 后来分成两大流派ATT 这边推商业化搞出了 System V加州大学伯克利分校那边在学术环境里持续改进形成了 BSD 系列。两边在系统调用、命令行为上慢慢出现差异程序换个平台就编译不过这在当时是个大麻烦。为了解决可移植性问题IEEE 组织牵头制定了一套标准叫POSIX全称是可移植操作系统接口。它规定了一组必须实现的系统调用和接口行为只要一个系统符合 POSIX用标准接口写的程序理论上就能在上面跑。这也是为什么你今天在 Linux 上学的东西换到别的类 Unix 系统上大部分还能用——大家遵守的是同一套约定。理解这一点你就明白为什么很多教材把 Unix 和 Linux 放在一起讲因为它们在接口层面是一脉相承的。2. Linux是怎么接棒的从一个人的爱好变成全球基础设施Unix 在商业和学术圈站稳脚跟后版权和授权的问题也越来越复杂很多人想要一套能自由使用、自由修改的系统。这个需求最终由一个芬兰学生和一场持续了几十年的自由软件运动共同满足了。这段历史你如果只听个大概很容易把“内核”和“操作系统”搞混所以我把关键节点拆开讲。2.1 1991年的那封邮件和一个不满足于Minix的人1991 年赫尔辛基大学的学生林纳斯·托瓦兹在用一套教学操作系统 Minix 学习内核知识但 Minix 是教学用途功能受限不允许随意修改和分发。他干脆自己动手基于 386 机器写了一个小小的内核并在 1991 年 8 月 25 日发了一封后来被无数次引用的帖子大意是“我在做一个免费的操作系统只是个爱好不会像 GNU 那样庞大和专业”。当时没人能预料到这个“只是爱好”的项目会在 1994 年发布 1.0 正式版再往后吞噬掉服务器市场的半壁江山。我特别想强调一个细节林纳斯一开始只写了内核也就是负责管硬件、管进程、管内存的那部分最底层的代码他并没有写编辑器、没有写编译器、也没有写 Shell。那些后来从哪来的这就引出了下一件事。2.2 GNU计划补上了那块缺失的拼图早在 1983 年理查德·斯托曼就发起了GNU 计划目标是打造一套完全自由的、类 Unix 的操作系统。这个计划非常成功产出了编译器 GCC、编辑器 Emacs、命令行工具集 Coreutils、Shell 等等一大堆组件唯独最关键的内核一直没做出来他们自己的内核项目 Hurd 因为设计过于激进长期难产。于是局面就变得非常巧合GNU 手里有完备的工具链缺一个能跑的内核林纳斯手里有一个能跑的内核缺外围的整套工具。两者一结合一套完整可用的自由操作系统就诞生了。这也是为什么严格来说我们平时说的“Linux 系统”应该叫做GNU/Linux。没人真的在意这个称呼之争但你得明白这个组合关系否则会以为 Linux 是一个人写出来的成品。2.3 内核和发行版是两件完全不同的事这是新手最容易混淆的地方我见过太多人问“我的 Linux 版本是多少”答案其实取决于他问的是哪个层面。内核是操作系统的心脏负责进程调度、内存管理、文件系统、网络协议栈、设备驱动这些最底层的事它由内核社区持续维护版本号像6.8.0这样更新频繁。发行版则是在内核之上把工具集、包管理器、桌面环境、配置文件、文档、软件仓库打包在一起的完整产品。你装的 Ubuntu、Debian、CentOS都是发行版。同一个内核可以对应无数个发行版同一发行版的不同版本又可能用不同的内核。搞清楚这个层级关系你以后看文档、查问题就不会再张冠李戴了。3. Linux内核的核心机制拆解敲命令时到底在发生什么命令行的每一条命令最终都要通过系统调用进入内核。如果你对内核里几个主要子系统有个大致印象学命令的时候就不会觉得它们是一堆孤立的字符串而是一张互相咬合的网。这一节我不追求把内核讲全只挑新手最该知道的四块来拆。3.1 进程管理与调度CPU到底在伺候谁在 Linux 眼里每一个正在运行的程序都是一个进程内核用一块叫task_struct的数据结构来记录它的状态、内存、打开的文件、优先级等信息。CPU 核心数有限而进程可能成百上千谁先跑、跑多久这就是调度器的活儿。现在默认的调度器叫做 CFS也就是完全公平调度器它的思路是不让任何进程饿死按权重分配 CPU 时间。这里有个实用概念叫nice 值范围是 -20 到 19值越小优先级越高。普通用户只能把自己的进程 nice 值调大也就是主动让出 CPU只有 root 才能调小。我遇到过备份任务把数据库查询拖慢的情况最后就是给备份进程加了nice -n 19让它占最少的 CPU问题就缓解了。想观察进程你可以用ps aux、top或者更好用的htop。3.2 内存管理与虚拟地址空间为什么程序看不到真实内存现代操作系统都玩一个魔术叫虚拟内存。每个进程都以为自己独占一整块连续的内存地址空间实际上这些虚拟地址通过页表映射到物理内存。真正做映射的硬件单元叫 MMU。当程序访问一个还没加载到物理内存的页时会触发缺页中断内核再把数据从磁盘读进来。这也解释了为什么程序启动时不会一次性占满内存。内存不够用的时候内核有个角色叫OOM killer会挑一个占用高、优先级低的进程杀掉来保命。生产环境上看到某个进程莫名其妙消失很多时候就是它干的。另外内存紧张时数据会被换出到swap分区但 swap 在机械硬盘上性能很差所以它只是保命手段不是扩容方案。用free -h能看清内存和 swap 的使用情况重点看 available 那一列而不是 free这是很多人看错的细节。3.3 虚拟文件系统VFS一切皆文件是怎么实现的“一切皆文件”听起来很玄靠的是一个叫VFS的抽象层。不管底层是 ext4、XFS 还是网络文件系统VFS 都提供统一的接口让你用同样的方式去读写。每种文件系统在 VFS 里都要实现一组对象主要包括超级块描述整个文件系统、inode描述一个文件本身的元数据、目录项描述路径关系和文件对象描述一个被打开的文件。inode 这个概念特别重要它存的是文件的权限、大小、时间戳和指向数据块的指针唯独不存文件名文件名是放在目录项里的。所以你可以给一个文件建多个硬链接它们共享同一个 inode。文件描述符则记录你打开了哪些文件标准输入是 0、标准输出是 1、标准错误是 2理解这三个数字是学重定向的基础。3.4 网络子系统与Unix域套接字从docker报错说起Linux 的网络协议栈实现了完整的 TCP/IP而所有网络通信在程序层面都通过socket抽象来完成。除了大家熟悉的 TCP/UDP socket还有一种 Linux 特有的东西叫Unix 域套接字它不走网卡只在本机进程之间通信速度快通常表现为/var/run/下的一个.sock文件。你肯定见过那条让人头大的报错cannot connect to the docker daemon at unix:///var/run/docker.sock。它本质上是客户端去找这个套接字文件要么是服务没起来要么是文件不存在要么是当前用户没权限访问。它不是网络断了是本地通信通道出了问题。同理数据库配置里有时会写mysqld_safe directory /var/run/mysqld for unix socket file dont exists说的也是这个套接字目录没创建。明白了域套接字的原理这类报错就不再可怕了。4. 发行版选型不同场景下的取舍逻辑知道了内核和发行版的区别接下来最现实的问题就是我该装哪一个这个问题没有标准答案得看你拿来干嘛。我把几条主要技术路线和典型场景拆开说顺便给出我的推荐逻辑。4.1 三条主流技术路线包管理器是最大的分水岭发行版之间最大的差异之一是包管理系统它决定了你怎么装软件、怎么升级、怎么解决依赖。家族代表发行版包格式包管理命令特点Debian系Debian、Ubuntu、Linux Mint.debapt / dpkg软件生态最丰富文档多新手友好Red Hat系RHEL、Rocky Linux、Fedora.rpmdnf / yum / rpm企业级稳定认证体系成熟Arch系Arch Linux、Manjaro.pkg.tar.zstpacman滚动更新软件最新适合折腾我个人的建议是纯新手先上 Ubuntu LTS因为遇到问题一搜一大把答案社区支持最好。如果你目标是从业方向偏运维或者企业环境可以尽早熟悉一下 RHEL 系因为很多企业的服务器都跑在这套体系上考认证也是围绕它来的。Arch 系适合喜欢自定义、想深入理解系统组成的人但不建议作为第一套学习环境。4.2 服务器、桌面、国产化环境的选型建议场景不同选择真的不一样。服务器场景我优先看稳定性和长期维护。Ubuntu 的 LTS 版本、Debian 的稳定版、Rocky Linux 都是不错的选择。它们对内核版本偏保守不追求最新但胜在长期不出乱子。桌面场景体验更重要。Ubuntu、Fedora、Linux Mint 都开箱可用驱动和输入法适配相对省心。你要是在 Windows 11 之外想装第二套系统做开发这几款都值得考虑。国产化环境这几年发展很快像麒麟、统信 UOS、openEuler 这类面向国内政务、金融、能源等场景的发行版都基于 Linux 内核做了本地化适配和安全加固。如果你的工作会接触到信创相关的项目提前熟悉一下它们的安装和使用流程会有帮助很多基础命令是通用的差异主要在外围工具和软件源配置上。我试过在国产系统上跑日常运维脚本绝大多数命令行为一致需要留意的往往是软件源地址和某些系统服务的命名习惯。4.3 LTS版本和滚动更新版本号背后的含义选版本时另一个绕不开的点是更新策略。Ubuntu 的版本号是“年份.月份”比如20.04就是 2020 年 4 月发布的。带 LTS 的是长期支持版服务器版支持五年桌面版支持三年不带 LTS 的是普通版支持期只有九个月左右适合尝鲜不适合长期用。如果你要搭学习环境直接选最新的 LTS比如 20.04 或 22.04稳。滚动更新则是另一种思路Arch 这类发行版没有大版本概念软件一直保持最新好处是永远用得上新东西代价是偶尔更新可能带来兼容问题需要你具备一定排查能力。新手很容易被“最新”诱惑我反倒劝你先在稳定版上把基础打牢等你能独立处理系统问题了再去折腾滚动更新不迟。5. 从零搭一套学习环境虚拟机安装与第一次登录理论讲了一堆该动手了。对新手来说直接拿真机装双系统风险太高一旦分区搞错可能连原来的系统都进不去。用虚拟机是最稳妥的方式装坏了删掉重来即可。这一节我把安装流程和背后的参数计算讲清楚你照着做基本不会翻车。5.1 虚拟机方案选择与硬件资源分配常见的虚拟机软件有几类各有侧重。VirtualBox 免费开源跨平台VMware Workstation 功能完善、性能好个人使用有免费版本如果你用的是 Linux 宿主机还可以直接用系统自带的 KVM性能接近原生。新手我一般推荐 VirtualBox 或 VMware图形界面友好出问题好查。资源分配是有讲究的不是越多越好。假设你的宿主机有 16GB 内存给虚拟机分 4GB 比较合适剩下 12GB 留给宿主机自己两边都不卡。CPU 别把所有核心都分给虚拟机一般给 2 核到 4 核因为虚拟机的 CPU 是共享宿主机核心的全给它反而会让宿主机卡顿。磁盘建议 40GB 起步选“动态分配”而不是“一次性分配”这样文件会随着数据增长慢慢变大不占地方。这些数字不是拍脑袋而是要在“虚拟机跑得动”和“宿主机不罢工”之间找平衡点。5.2 分区方案设计swap到底该给多大安装时最让人纠结的就是分区。我分享一套常用的方案适合学习和一般使用。挂载点建议大小说明/boot 或 EFI512MB 到 1GB存放引导文件EFI 分区必须存在swap内存大小以内用于内存不足时应急和休眠/20GB 到 30GB系统和软件安装位置/home剩余空间用户数据单独分区方便重装保留数据关于swap给多大有个流传很广的经验规则如果不用休眠swap 给内存的一半或等于内存即可如果要用休眠功能swap 需要不小于物理内存因为休眠时要把整个内存内容写进 swap。这里有个细节很多人忽略——休眠是把运行状态写入磁盘所以空间必须够否则休眠会失败。另外如果你把/home单独分区重装系统时只要格式化/和/boot用户数据就能保留下来这个习惯我强烈建议养成。5.3 装完之后的第一批命令与验证系统装好第一次登录别急着关机。先跑几条命令确认环境是否正常同时熟悉手感。# 看我是谁、当前主机名 whoami hostname # 看内核版本和系统架构这是判断环境的关键 uname -a # 查网络地址现代系统用 ip 替代了老的 ifconfig ip addr show # 看磁盘空间和内存使用 df -h free -h # 看块设备和分区布局 lsblk # 查看系统服务状态systemctl 是核心管理工具 systemctl statusuname -a这条特别值得留意它会告诉你内核版本、主机名、架构、编译时间等出问题时别人第一句往往就是“把你的 uname -a 贴出来”。ip addr是查 IP 地址的现代命令老的ifconfig在不少新发行版上默认都没装这属于环境变化的常见坑。我第一次装完系统就卡在“为什么 ifconfig 命令找不到”后来才知道是被ip取代了。6. 新手最容易踩的坑与排查思路讲理论容易真上手就会遇到各种报错。我把这些年带新人时见到最多的问题整理出来按阶段归类配上排查思路。这部分是纯经验文档里通常不会写这么细。6.1 安装阶段最常见的问题虚拟机装完黑屏或卡住不动。十有八九是显卡或启动模式的问题。可以试着在虚拟机设置里把显卡加速关掉或者把启动方式在 BIOS 和 UEFI 之间切换一下。还有一个常见原因是下载的镜像不完整校验一下文件的哈希值能排除掉。虚拟机上不了网。这多半是网络模式选错了。虚拟机一般有 NAT、桥接、仅主机三种模式。NAT 模式下虚拟机能上网但外部访问不到它适合只上网查资料桥接模式会让虚拟机像一台独立设备一样接入你的局域网能被其他机器访问适合做服务器实验。我建议先用 NAT 保证能上网等要做服务访问测试再换桥接。ip addr看到的是10.0.2.x这类地址基本就是 NAT 模式。安装时中文显示成方块或乱码。这通常和系统的 locale 设置有关。可以在安装时先选英文装完再配置中文环境和输入法这样能避开安装界面字体缺失导致的乱码。6.2 命令、权限、编码类问题速查到了日常使用阶段下面这几类问题出现频率最高我做成表格方便你对照。现象可能原因排查与解决Permission denied权限不足或文件属主不对用ls -l看权限必要时sudo改属主用chown改权限用chmod解压后文件名乱码压缩包用了非 UTF-8 编码用unzip -O GBK指定编码或解压后用convmv转换文件名命令找不到软件没装或不在 PATH 里用which、command -v确认装包用apt install或dnf installdocker.sock 连不上服务未启动或用户无权限先systemctl status docker再把用户加入 docker 组新建用户后不能 sudo没加入管理组用usermod -aG sudo 用户名添加改动后需重新登录生效这里展开说两个。新建用户是很基础但容易漏掉权限的操作。用useradd建的用户默认连家目录和登录 Shell 都可能没配好所以我更推荐adduser它会交互式地帮你把家目录、密码、Shell 一次配齐。建完如果发现这人不能执行管理命令记得把人加进 sudo 组而且分组变更要重新登录才生效这个坑我见过不止一个人踩。解压乱码也是老问题。Windows 上打的压缩包经常用 GBK 编码存文件名拿到 Linux 上解压出来就是一堆乱码。unzip有个-O参数可以指定编码比如unzip -O GBK 文件名.zip。不过要注意不是所有版本的 unzip 都支持这个参数如果你的版本不支持可以先用unzip解出来再用convmv工具批量转换文件名编码。这种问题看着小但会让人怀疑自己的操作其实只是编码历史遗留问题。6.3 学习路径上的几点建议最后分享几条我带人时反复强调的经验。第一别在发行版之间反复横跳。有人这周装 Ubuntu下周换 Manjaro再来装 Kali结果哪套都没摸熟。选定一套 LTS 用上半年把命令和思维方式练扎实比什么都强。第二养成看日志的习惯。系统出问题先看journalctl -xe和对应服务的日志八成问题日志里写得清清楚楚比瞎猜高效得多。第三理解比背诵重要。你背下chmod 755却不知道 7 代表读写执行遇到权限问题还是懵搞懂权限是三组三位八进制任何组合你都能自己算。至于那条cannot connect to the docker daemon之类的报错我这些年最大的体会是——不要被英文报错吓到把句子拆开逐词读关键词通常在最后。很多所谓的疑难杂症翻译成大白话之后就是“文件不存在”或者“权限不够”对症下药就行。等你把这一篇里的系统层次、内核机制、发行版差异、安装流程都过了一遍再回头看那些命令你会发现它们不再是零散的符号而是一整套可以推理、可以预测的系统。