Linux 学习笔记(二):终端、Shell 与文件系统——走进 Linux 的日常工作现场

第二课:Linux 的工作现场——终端、Shell、文件系统与权限

本课定位:第一课回答了“Linux 是什么、为什么存在、内部大致有哪些层”。这一课开始进入每天真正使用 Linux 的现场:你怎样向系统发出命令,命令运行在哪里,文件放在哪里,为什么有些操作被拒绝,以及串口和 SSH 到底分别连接到了什么。

1. 本课目标

学完本课后,应当能够回答以下问题:

  1. 终端、终端模拟器、Shell 和命令分别是什么?
  2. 一行命令从敲下回车到出现输出,经历了什么?
  3. Linux 的路径、当前目录、绝对路径和相对路径分别是什么意思?
  4. /home/etc/dev/proc/sys/run 等目录为什么存在?
  5. 用户、组、root、sudo 和文件权限分别解决什么问题?
  6. 标准输入、标准输出、标准错误、管道和重定向如何组合?
  7. 串口 Shell、SSH Shell 与本机终端有什么共同点和不同点?
  8. 怎样在不破坏系统的前提下观察 Linux?

2. 你面对的不是“黑框”,而是一条工作链

刚开始使用 Linux 时,终端窗口很容易被理解成“一个可以输入命令的黑框”。这不算错,但太粗糙。实际至少有几层东西在协作:

键盘输入
  ↓
终端模拟器或串口程序
  ↓ 字符流
Shell(例如 Bash)
  ↓ 解析命令、启动程序、建立管道和重定向
普通用户程序
  ↓ 系统调用
Linux 内核
  ↓
文件、进程、终端设备、网络设备、硬件

如果你通过 SSH 连接远端主机,或通过串口连接一台无屏设备,前半段会不同,但 Shell、普通程序和内核之间的关系仍然相似。

2.1 终端的历史含义

早期大型计算机不一定自带显示器和键盘。用户通过电传打字机或独立终端与主机通信。终端负责输入和输出,真正运行程序的是远处的主机。

今天的图形化 Linux 桌面里,常见的“终端窗口”通常是终端模拟器:它用图形窗口模拟传统字符终端,向其中运行的 Shell 传递字符,并显示程序输出。

所以“打开终端”并不等于“打开了 Linux 内核”。你通常是启动了一个图形程序,它再为你启动一个 Shell。

2.2 Shell 是命令解释器

Shell 的原义是“外壳”。内核处于系统核心,Shell 作为用户交互层,帮助你:

  • 读取输入的一行文本;
  • 按规则拆分、展开和解释它;
  • 找到要执行的程序;
  • 创建子进程运行程序;
  • 连接文件、终端、管道和网络输入输出;
  • 等待结果并显示下一个提示符。

Bash 是最常见的 Shell 之一;还有 Zsh、Fish、Dash、BusyBox ash 等。它们的交互体验和脚本语法有差异,但都在做“把文字组织成程序执行”的工作。

先查看当前 Shell:

printf '%s\n' "$SHELL"
ps -p $$ -o pid,ppid,tty,comm,args

这里的 $$ 是当前 Shell 的进程号。第二条命令没有修改系统,只是让 ps 显示当前 Shell 的 PID、父进程、关联终端和启动参数。

2.3 提示符不是装饰

你常会看到类似:

caige@host:~/work$ 

它通常包含用户名、主机名和当前目录。末尾的符号也常表达权限:

  • $:普通用户;
  • #:root 用户。

这是一种惯例,不是内核强制规则。提示符可以被用户改成任何样子,所以真正判断身份要使用:

id
whoami

在不同系统的本地终端、SSH 会话或串口会话中,可能看到:

user@host:~$ 
root@device:~# 

前者通常表示普通用户,后者通常表示 root 用户。它说明你进入了某台机器的命令解释环境;提示符的外观可以自定义,真正的身份仍应以 id 的输出为准。


3. 一条命令如何被理解

先看一条简单命令:

ls -l /etc

它可以粗略分成三部分:

ls       -l       /etc
│         │         │
程序名    选项       参数
  • ls 是程序名;
  • -l 是选项,要求使用较详细的列表格式;
  • /etc 是参数,告诉程序要列出哪个目录。

Shell 并不“天然懂得” ls 怎么列目录。它先按照自己的语法处理这行文字,再根据 PATH 环境变量寻找可执行文件,最后创建进程运行它。ls 再通过系统调用请求内核读取目录内容。

3.1 命令名从哪里找到

查看搜索路径:

printf '%s\n' "$PATH"

输出通常是一串用冒号分隔的目录,例如:

/usr/local/bin:/usr/bin:/bin

当你输入 ls,Shell 会按顺序在这些目录中查找同名可执行文件。可以这样确认实际找到的是哪一个:

command -v ls
type ls

type 特别有用,因为一个名字不一定是独立程序:它可能是 Shell 内建命令、别名、函数或外部可执行文件。

type cd
type echo
type sudo

通常 cd 是 Shell 内建命令。原因很直接:改变目录必须改变当前 Shell 进程的状态。如果把 cd 做成一个独立子进程,它只能改变自己的目录,退出后你的 Shell 仍留在原地。

3.2 引号、空格和通配符

Shell 不会把输入机械地按空格切开;它还要处理引号、变量、通配符和转义符。

printf '<%s>\n' hello world
printf '<%s>\n' "hello world"
printf '<%s>\n' 'hello world'

第一条会得到两个参数,后两条把 hello world 作为一个参数。单引号通常保留其中文字的字面含义;双引号通常仍允许 $变量 展开。

name='Taishanpi'
printf '%s\n' "$name"
printf '%s\n' '$name'

通配符由 Shell 展开,不是 ls 自己理解的:

printf '%s\n' /etc/*.conf

这会在当前系统中匹配 /etc 下以 .conf 结尾的文件。因为匹配结果取决于真实文件,请先把它当作观察命令,不要对通配符匹配结果执行删除或覆盖操作。

3.3 环境变量与当前目录

环境变量是一组传递给新进程的名称和值。常见例子:

printf 'HOME=%s\n' "$HOME"
printf 'USER=%s\n' "$USER"
printf 'PATH=%s\n' "$PATH"
pwd

HOME 是当前用户的家目录,PATH 决定命令搜索位置,pwd 显示当前工作目录。它们都属于用户空间约定,不是“硬盘上的固定地址”。例如 root 的家目录常为 /root,普通用户的家目录通常在 /home/用户名


4. 从 / 开始:路径与目录树

Linux 文件系统只有一个目录树根:/。无论硬盘、U 盘、临时内存文件系统还是网络文件系统,挂载后都会出现在这棵树的某个位置。

/
├── home
│   └── caige
├── etc
├── usr
├── var
├── dev
├── proc
├── sys
├── run
└── tmp

4.1 绝对路径与相对路径

/ 开头的路径是绝对路径,从整个目录树的根开始计算:

/etc/os-release
/home/caige/workspaces

不以 / 开头的路径是相对路径,从当前工作目录开始计算:

notes/02-terminal-shell-filesystem-permissions.md
../materials

两个特殊名字几乎每天都会用到:

  • .:当前目录;
  • ..:当前目录的父目录。

安全练习:

pwd
ls
ls .
ls ..
cd ..
pwd

cd .. 会改变当前 Shell 的工作目录。结束练习后可用 cd - 返回上一个目录,或 cd 直接回到自己的家目录。

4.2 文件名不是“文件类型”

Linux 不通过扩展名强制决定文件类型。report.txtprogramImage 都只是文件名。能否执行主要由权限位、文件内容、解释器声明和 CPU 架构共同决定。

使用 file 观察真实类型:

file /bin/ls
file /etc/os-release
file /dev/null

你会看到普通可执行文件、文本文件和设备文件之间明显不同。设备文件后面会在第 6 节解释。

4.3 隐藏文件

Linux 中名字以 . 开头的文件或目录默认不会被普通 ls 显示:

ls -la ~

例如 .bashrc 常用于 Bash 的交互配置。它不是安全机制;“隐藏”只是一种显示习惯。重要配置依然需要正确的权限和备份。


5. 常见目录各自负责什么

Linux 发行版之间会有差异,但下表能帮助你读懂大多数系统。

路径 通常内容 为什么你会关心
/ 根目录 所有路径的起点
/home 普通用户家目录 个人代码、配置和文件通常放这里
/root root 的家目录 不等于整个根目录 /
/etc 系统级配置 网络、服务、用户等配置常在这里
/usr 大量用户空间程序、库、共享资源 /usr/bin/usr/lib 很常见
/bin/sbin 基础命令的兼容入口 现代发行版常把它们链接到 /usr/bin/usr/sbin
/var 会不断变化的数据 日志、缓存、队列、数据库数据等
/tmp 临时文件 文件可能被清理,不适合放长期成果
/run 本次启动期间的运行状态 PID 文件、套接字、临时运行信息,重启后通常消失
/boot 引导相关文件 普通 PC 常放内核和引导器配置;嵌入式设备布局可能不同
/dev 设备节点 串口、磁盘、终端等的用户空间入口
/proc 进程和内核状态的虚拟视图 cpuinfomeminfocmdline 等观察入口
/sys 设备模型与驱动状态的虚拟视图 网卡、GPIO、总线、模块、供电等观察入口
/mnt/media 临时或可移动介质挂载点 U 盘、数据盘常出现在这里
/opt 可选的附加软件 第三方软件有时使用

5.1 /etc 不是“所有配置都在这里”

/etc 是系统级配置的重要位置,但今天的软件也可能在以下位置读取配置:

  • 用户家目录中的 .config/
  • /usr/lib/ 的默认配置;
  • /run/ 中运行时生成的配置;
  • /var/lib/ 中服务自己的数据;
  • 内核命令行、设备树或固件文件。

因此排错时不能只猜“配置一定在 /etc”。要先看该程序的文档、日志和启动参数。

5.2 /proc/sys 不是普通磁盘文件

下面命令读起来像打开文件:

cat /proc/cpuinfo
cat /proc/meminfo | head
cat /sys/class/net/wlan0/operstate

/proc/sys 多数内容由内核在读取时动态生成,不一定真正占据磁盘块。它们是内核向用户空间暴露状态和控制入口的接口。

这也带来一个重要习惯:有些虚拟文件可写,而写入会立即影响内核行为。 初学阶段先以读取为主。看到网上的 echo 某个值 > /proc/...> /sys/... 命令时,先弄清它改变哪一项内核或设备状态,再考虑执行。

5.3 /dev 把设备呈现为可打开的对象

例如:

ls -l /dev/tty*
ls -l /dev/null /dev/zero

/dev/ttyUSB0 这类名字可能对应 USB 串口适配器;/dev/ttyS*/dev/ttyAMA*/dev/ttyFIQ0 等则可能对应 SoC UART。名字与驱动、硬件平台有关,不能机械套用。

/dev/null 是一个经典设备:写入它的数据会被丢弃,读取通常立即得到文件结束。它适合说明“设备也可以通过文件描述符读写”,不是让人随意丢弃有价值的输出。


6. 文件系统、挂载和“磁盘在哪儿”

“目录”和“磁盘分区”不是同一个概念。

  • 目录是文件系统命名空间中的位置;
  • 分区是块设备上的一段范围;
  • 文件系统是把块组织成目录、文件、权限和元数据的格式;
  • 挂载是把某个文件系统接入目录树某一点的动作。
块设备 /dev/nvme1n1p5
       ↓
ext4 文件系统
       ↓ 挂载
目录树中的 /

你本机当前根文件系统正是一个 ext4 文件系统,挂载在 /。SDK 之前放在 NTFS 数据盘时,厂商 build.sh 拒绝继续;复制到 ext4 工作区后才通过检查。这个例子说明:路径看起来像普通目录,底层文件系统类型却可能影响权限、符号链接、大小写、时间戳和构建工具行为。

安全观察命令:

findmnt /
df -hT
lsblk -f
  • findmnt /:从挂载关系看根目录来自哪里;
  • df -hT:看已挂载文件系统的容量和类型;
  • lsblk -f:看块设备、分区、文件系统和挂载点。

不要把 df 的输出理解成“物理磁盘的全部布局”。它只关注已挂载的文件系统;而 lsblk 更接近设备和分区视角。


7. 用户、组与 root:为什么系统会拒绝你

Linux 是多用户系统。即使你一个人使用电脑,系统仍以用户身份、用户组和权限规则组织资源。

进程以某个用户身份运行
        ↓
请求访问一个文件、设备或系统资源
        ↓
内核根据 UID、GID、权限位、ACL、能力与安全策略判断
        ↓
允许,或者返回 Permission denied

7.1 UID、GID 和组

  • UID:用户标识符;
  • GID:主组标识符;
  • 附加组:用户还可以属于多个组,用于共享权限。

观察自己的身份:

id
groups

在 Linux 主机上,串口权限常通过 dialoutuucp 或发行版定义的其他组授予。不要因为“打不开 /dev/ttyUSB0”就立刻使用 root;先查看设备权限和自己的组。

ls -l /dev/ttyUSB0
id

如果设备不存在,上面的第一条会报错;那通常意味着当前没有这个设备节点或名字不同,而不是权限问题。

7.2 root 是什么

root 通常指 UID 为 0 的超级用户。它可以绕过很多普通的文件权限检查,因此能做系统管理,但也更容易把错误的命令作用到整个系统。

root 不是“更懂 Linux 的用户”,也不是普通操作的默认身份。日常编辑代码、查看日志和运行构建,都应优先使用普通用户。需要明确的系统管理权限时,再使用 sudo 获得短时间、单次命令范围内的提升。

sudo -v
sudo systemctl status ssh

第一条可能要求验证你的密码,但不修改系统;第二条只是读取服务状态。sudo 的含义不是“请永远相信我”,而是“在允许的策略下,以另一身份执行这条明确的命令”。

7.3 susudo 的区别

su                 切换到另一个用户的 Shell
sudo 某条命令       只以更高权限运行这一条命令
sudo -i            打开一个 root 登录式 Shell

它们都可能获得高权限,但使用场景不同。某些精简系统或恢复环境可能只提供 root Shell;作为日常开发习惯,应尽量让高权限操作短、小、可审查。

7.4 文件权限的十个字符

执行:

ls -l /etc/os-release

可能看到类似:

-rw-r--r-- 1 root root ... /etc/os-release

最前面的十个字符可这样读:

- rw- r-- r--
│  │   │   └─ 其他用户的权限
│  │   └───── 文件所属组的权限
│  └───────── 文件所有者的权限
└──────────── 文件类型:- 普通文件,d 目录,l 符号链接等

每组三个字符分别是:

  • r:read,读取;
  • w:write,写入;
  • x:execute,执行。

对于普通文件,x 常表示可作为程序执行。对于目录,含义更微妙:

  • r:可以读取目录条目列表;
  • w:可以在目录中创建、删除或改名条目,通常还受其他条件影响;
  • x:可以穿过该目录访问已知名字的内容。

所以目录缺少 x 时,即使你能看到名字,也可能无法进入或访问里面的文件。

7.5 chmodchown 为什么要谨慎

chmod 改权限,chown 改所有者。它们是必要工具,但初学者不应把它们当成“权限报错万能修复键”。

尤其要避免:

chmod -R 777 某个目录
sudo chown -R 当前用户 /

第一条会把目录树递归地开放给所有人读、写、执行;第二条可能破坏整个系统的所有权和安全边界。遇到权限问题,更好的顺序是:

  1. 确认实际目标路径,没有拼错;
  2. ls -ld 路径 查看目录本身的属主与权限;
  3. id 查看当前用户和组;
  4. 判断操作本来是否应该由普通用户完成;
  5. 只对必要的一个文件或目录做最小改动。

8. 标准输入、标准输出与标准错误

每个普通进程启动时,通常都带有三条最基本的文件描述符:

编号 名称 默认去向
0 标准输入,stdin 键盘或上游程序
1 标准输出,stdout 终端窗口或下游程序
2 标准错误,stderr 终端窗口

程序把正常结果写到 stdout,把错误或诊断消息写到 stderr。它们默认都显示在终端,所以初看时很像同一种输出;但 Shell 可以把它们分别接到不同位置。

8.1 管道:把一个程序的输出交给另一个程序

ip link | less

| 会创建管道,把左侧命令的标准输出送到右侧命令的标准输入。这个例子把较长的网卡信息交给 less 分页查看。

再看一个:

findmnt | grep -E 'ext4|ntfs'

这不是魔法:findmnt 输出文本,grep 从文本中筛选包含 ext4ntfs 的行。管道是 Unix 工具组合能力的核心之一。

注意:普通管道默认只连接 stdout。若左侧程序把错误写到 stderr,它仍会直接显示在终端。

8.2 重定向:改变输入和输出的位置

常见符号:

> 文件       把标准输出写入文件;会覆盖已有文件
>> 文件      把标准输出追加到文件末尾
< 文件       让程序从文件读取标准输入
2> 文件      把标准错误写入文件;会覆盖已有文件
2>&1         让标准错误去往标准输出当前去向

为了理解,先在自己可写的临时目录中练习:

mkdir -p ~/tmp/shell-lesson
printf 'first line\n' > ~/tmp/shell-lesson/example.txt
printf 'second line\n' >> ~/tmp/shell-lesson/example.txt
cat ~/tmp/shell-lesson/example.txt

> 真的会覆盖目标文件。把练习限制在新建的专用目录,是为了让错误不会伤到项目文件或系统配置。

保存命令的正常输出和错误输出:

ls /etc /path/that-does-not-exist > ~/tmp/shell-lesson/out.txt 2> ~/tmp/shell-lesson/err.txt
cat ~/tmp/shell-lesson/out.txt
cat ~/tmp/shell-lesson/err.txt

第二个路径故意不存在,因此它的报错进入 err.txt,而 /etc 的正常列表进入 out.txt。实际工作中,这种分离很适合保存构建日志。

8.3 不要迷信 2>&1

2>&1 的意思是把 stderr 接到 stdout 当前的位置,因此顺序很重要:

command > log.txt 2>&1

这里两种输出都会进入 log.txt。而:

command 2>&1 > log.txt

会先让 stderr 指向当时的终端 stdout,再把 stdout 改到文件;结果可能不是你想要的。初学阶段只需要记住常见、安全的写法:

command > log.txt 2>&1

9. 进程、前台与后台

Shell 启动外部程序时,程序会成为一个进程。进程不是“一个应用图标”,而是一个正在运行、拥有 PID、地址空间、打开文件和权限身份的执行实体。

观察当前终端中的进程:

ps -ef | head
ps -p $$ -o pid,ppid,tty,stat,comm,args

9.1 前台任务

前台任务通常占用当前终端:Shell 等待它结束,你的键盘输入也交给它。例如:

sleep 30

执行后,30 秒内不会出现新的 Shell 提示符。按 Ctrl+C 会向前台进程组发送中断信号,通常使它结束。Ctrl+C 不是“关闭终端”,而是终端驱动配合 Shell 和信号机制提供的约定。

9.2 后台任务

命令末尾加 & 可以让 Shell 把任务放到后台:

sleep 30 &
jobs

这适合短时间的交互实验。长期服务不应靠“终端后面挂一个 &”管理;发行版通常使用 systemd、OpenRC 或 BusyBox init 的服务机制。

9.3 进程与线程不是一回事

初步理解即可:进程通常拥有独立的虚拟地址空间和资源视图;线程是同一进程内部可以并发执行的多个执行流。ps 主要从进程视角展示信息,某些参数可以进一步显示线程。

以后你看到“SSH 连不上”“Wi-Fi 没起来”时,需要区分:是程序没有启动、启动后退出、仍在运行但配置错误,还是内核驱动层根本没有设备。不要把所有问题都归为“程序卡住了”。


10. 串口、SSH 与本机终端:同一类交互,不同链路

无屏设备最容易混淆的地方之一,是把“我打开了一个终端”误认为“我已经连上远端设备”。实际上终端窗口只是本机程序;它到底连接到谁,取决于底层链路。

本机终端
  图形终端模拟器 → 本机 Shell → 本机 Linux 内核

串口终端
  串口程序 → USB-TTL / UART 字节流 → 设备串口 → 设备 Shell

SSH 终端
  ssh 客户端 → TCP/IP 网络 → sshd → 远端设备的伪终端与 Shell

10.1 串口为什么是保底入口

嵌入式 Linux 设备的调试串口通常可以看到 Bootloader、内核和用户空间启动日志。它不依赖:

  • Wi-Fi 驱动已经工作;
  • 有效 IP 地址;
  • 路由器或 DHCP;
  • SSH 服务已经启动;
  • 根文件系统中的用户配置已经正确。

因此,当系统没有启动、没有网或 SSH 不通时,先看串口。串口参数、信号电平和接线方式由具体硬件决定;常见原则是 TX/RX 交叉、GND 共地,且不能把不确定用途的供电引脚随意连接。

10.2 SSH 为什么适合日常使用

当系统已经能上网且 OpenSSH server 正常运行时,SSH 比串口更适合日常开发:

  • 复制文本方便;
  • 可使用多个窗口;
  • 可传输文件;
  • 可进行远程编辑、Git 操作和调试;
  • 不会被内核启动日志持续冲掉输入行。

但 SSH 是更靠后的能力。它失败时,应按层排查:板是否启动、网卡是否出现、是否关联 Wi-Fi、是否获得 IP、是否能到达主机、sshd 是否运行、账号和密钥是否正确。

10.3 你在哪台机器上执行命令

这是远程与嵌入式 Linux 学习中必须养成的习惯。每次执行命令前先问:它运行在本机,还是远端目标设备?

任务 通常运行位置
Git、编辑源码、交叉编译 x86_64 Linux 开发主机
build.sh、Buildroot、内核编译 x86_64 Linux 开发主机
查看 U-Boot/内核早期日志 开发主机上的串口程序接收板端输出
uname -aip link、挂载 rootfs 远端 Linux 目标设备
SSH 登录命令 ssh 用户@地址 开发主机发起,远端设备接收

例如,主机上的 uname -m 很可能输出 x86_64,而许多 ARM 设备上的同一命令会输出 aarch64。命令一样,观察对象不同。


11. 帮助系统:先问系统,再问搜索引擎

Linux 的命令往往选项很多,死记硬背效率很低。先建立查帮助的习惯:

ls --help | less
man ls
man hier
man 5 passwd
  • 命令 --help:快速列出该程序支持的选项;
  • man 命令:查看手册页;
  • man hier:某些系统提供目录层次结构说明;
  • man 5 passwd:查看第 5 类手册页中的文件格式说明,而不是同名用户管理命令。

常见手册页分类:

章节 通常内容
1 用户命令
2 系统调用
3 库函数
4 设备和特殊文件
5 文件格式与配置文件
8 系统管理命令

嵌入式 Buildroot 系统通常比桌面发行版小,未必安装 man 页面。这时可在开发主机查手册,也可用 命令 --help、项目文档和源码注释辅助理解。


12. 一套安全的日常观察命令

下面命令以“读取、列出、查询”为主,适合作为刚开始的工具箱。

12.1 身份与位置

id
hostname
pwd
uname -a

12.2 文件与目录

ls -lah
findmnt
df -hT
lsblk -f

12.3 进程与服务

ps -p 1 -o pid,comm,args
ps -ef | less
systemctl --failed

最后一条只适合使用 systemd 的系统。Buildroot 默认可能使用 BusyBox init,因此没有 systemctl 并不代表系统坏了;它只说明服务管理器不同。

12.4 网络

ip link
ip address
ip route
ping -c 3 1.1.1.1

ping -c 3 1.1.1.1 会发送三个 ICMP 回显请求。它适合在已知网络可用的环境测试连通性;若网络策略禁止 ICMP,失败不必然表示完全不能联网。

12.5 内核与设备

dmesg | tail -n 80
lsmod
cat /proc/cmdline
ls -l /sys/class/net

不同发行版可能限制普通用户读取 dmesg。不要为了看一眼日志就不加判断地把整台系统切到 root;先理解该发行版的权限策略。


13. 一次受控的小练习:建立自己的实验目录

学习命令时,最好的习惯是把会产生文件的实验限制在一个明确目录中。下面示例只会在自己的家目录下创建内容:

mkdir -p ~/linux-learning/lab-02
cd ~/linux-learning/lab-02
pwd
printf 'hello from lesson 02\n' > hello.txt
ls -l
cat hello.txt

接着观察权限和类型:

stat hello.txt
file hello.txt

最后验证标准错误分流:

ls hello.txt missing.txt > normal.log 2> error.log
cat normal.log
cat error.log

这个实验故意让 missing.txt 不存在。正常结果和报错分别写入两个文件;请先读懂它们,再继续下一步。练习完成后,即使你删除整个 ~/linux-learning/lab-02,影响也只在自己的练习目录内。


14. 常见误解

误解 1:终端就是 Shell

终端模拟器、SSH 客户端或串口程序负责传递字符;Shell 是解释命令的程序。它们常一起出现,但不是同一个东西。

误解 2:# 就是“危险模式”

# 通常表示 root 提示符,但提示符本身可以修改。真正关键是 id 的输出,以及你准备执行的命令是否会改变系统。

误解 3:看见 Permission denied 就 sudo

权限被拒绝可能是路径错误、设备不存在、文件系统只读、ACL 或安全策略限制。sudo 只能改变执行身份,不能修复错误路径、坏驱动或只读介质。

误解 4:/root 就是 /

/ 是整个目录树的根;/root 只是 root 用户通常的家目录,类似普通用户的 /home/用户名

误解 5:所有 /proc/sys 文件都存在于硬盘

它们大多是内核动态提供的虚拟接口。读取通常是观察状态,写入可能立即改变系统或硬件行为。

误解 6:删除文件只和它所在目录的权限有关

删除一个文件主要受父目录的写与执行权限控制,而不是只看文件本身是否可写。这是初学权限时很反直觉的一点。

误解 7:管道会自动传递所有报错

普通 | 默认只连接标准输出。标准错误仍会走向终端,除非显式重定向。

误解 8:能 SSH 就不需要串口

SSH 依赖目标系统、网络和服务都已正常。启动早期、Wi-Fi 故障或 rootfs 无法挂载时,串口才是保底入口。

误解 9:所有 Linux 都有 systemctl

systemctl 是 systemd 的管理客户端。精简系统可能使用 BusyBox init,其他发行版也可能采用不同初始化体系;同样是 Linux 内核,用户空间工具可以不同。


15. 面向 Linux 项目的工作习惯

从现在起,把工作明确分成三类位置:

开发主机的家目录
  ├─ 源码工作区:例如 ~/workspaces/...
  ├─ 学习项目:例如 ~/linux-learning/...
  └─ 临时实验:例如 ~/tmp/...

NTFS 数据盘
  └─ 原始资料、下载包和参考副本

远端 Linux 设备
  ├─ 串口:用于早期启动日志与恢复
  └─ SSH:用于网络正常后的日常操作

对应的规则是:

  1. 在适合项目要求的工作区构建软件;
  2. 原始资料、下载包和重要配置不随意改动;
  3. 远端命令先标明“这是在目标设备执行”;
  4. 带有 >, rm, dd, mkfs, mount, flash 等写入或破坏含义的命令,执行前先确认目标;
  5. 不因为方便而长期使用 root;
  6. 碰到异常,先保存完整输出和当时所在机器,再尝试修复。

这几条听起来朴素,却会直接决定之后排查“本机编译问题、网络问题、串口问题还是远端系统问题”时是否混乱。


16. 本课总结

  1. 终端程序负责字符输入输出,Shell 负责解析命令和启动程序;它们不是 Linux 内核。
  2. 命令名、选项、参数、变量、引号和通配符都由 Shell 与程序共同处理。
  3. Linux 以 / 为唯一目录树根;绝对路径从 / 开始,相对路径依赖当前目录。
  4. 目录、分区、文件系统和挂载是四个不同概念;同一个路径背后的文件系统类型会影响软件行为。
  5. /dev/proc/sys 是理解设备与内核状态的重要入口,其中一些文件写入会立即产生影响。
  6. 用户、组和权限是内核的资源保护机制;root 权限应当短、小、明确,而不是日常默认身份。
  7. stdin、stdout、stderr、管道和重定向让小程序可以组合成可靠的工作流。
  8. 串口和 SSH 都能给你 Shell,但串口覆盖更早的启动阶段,SSH 依赖系统和网络已经正常。
  9. 远程或嵌入式开发时,先确认命令是在本机还是远端设备执行;同一条命令在两处可能观察到完全不同的系统。

17. 课后练习

17.1 开发主机观察练习

在 Linux 开发主机执行以下命令,记录输出中的关键信息:

id
pwd
printf '%s\n' "$SHELL"
type cd
findmnt /
df -hT
lsblk -f
ps -p 1 -o pid,comm,args
ip link

回答:

  1. 你当前是谁?属于哪些组?
  2. 当前 Shell 是什么?cd 为什么不是普通外部程序?
  3. 根目录 / 位于哪个文件系统,是什么类型?
  4. PID 1 是什么程序?
  5. 主机上有哪些网络接口?

17.2 文件与重定向练习

~/linux-learning/lab-02 中完成第 13 节实验,再回答:

  1. >>> 的区别是什么?
  2. 为什么报错进入 error.log 而不是 normal.log
  3. 如果把 2> error.log 改成 2>&1,结果会怎样?
  4. 为什么练习文件不应直接放在 /etc/usr 或 SDK 源码根目录?

17.3 串口观察练习

如果你有一台可通过串口登录的 Linux 设备,且不改变任何设置,可以执行:

id
pwd
uname -m
cat /proc/cmdline
ip link

记录这些结果与开发主机的差异。不同设备的发行版、内核版本、目录布局、服务管理器和命令集合可能不同;观察到差异是正常的,先确认运行环境再解释结果。

17.4 思考题

  1. 为什么 cd 必须由 Shell 自己实现?
  2. 为什么 /proc 中的内容不一定占用真实磁盘空间?
  3. 为什么删除文件与父目录权限有关?
  4. 串口和 SSH 都能出现提示符,它们最重要的差别是什么?
  5. 为什么 ARM 设备上的 uname -m 可能与主机不同,却仍能由主机编译它的程序?
  6. 为什么第一版 Buildroot 要避免同时启用两套 SSH 服务?

18. 术语表

术语 含义
Terminal 终端;今天常指终端模拟器或远程字符交互环境
Shell 命令解释器,例如 Bash 或 BusyBox ash
Prompt Shell 等待输入时显示的提示符
PATH Shell 搜索可执行程序的一组目录
Working directory 当前工作目录
Absolute path 从根目录 / 开始的路径
Relative path 相对当前工作目录解释的路径
Filesystem 组织文件、目录和元数据的格式与实现,例如 ext4
Mount 将一个文件系统接入目录树某位置
UID / GID 用户标识符 / 组标识符
root UID 为 0 的超级用户
stdin / stdout / stderr 标准输入、标准输出、标准错误
Pipe | 连接进程输入输出的内核机制
Redirection 使用 >>>< 等改变输入输出去向
PID 进程标识符
TTY 终端设备的统称,也可指伪终端
SSH 基于加密网络连接的远程登录与命令执行协议
UART 通用异步收发器;嵌入式设备常用作调试串口

19. 延伸阅读

下一课:进程、服务与启动——从 PID 1、日志、systemd/BusyBox init,到 Linux 如何从内核进入用户空间的过程。

posted @ 2026-08-10 16:23  浪迹天涯的鸟  阅读(0)  评论(0)    收藏  举报