写在前面
上一篇 《Linux系统编程(一):从 UNIX 到 Linux|开源生态、发行版与学习路线》,梳理了 UNIX‑Linux 渊源、发行版差异与整体学习路线。
本篇正式进入 Linux 实操。很多初学者机械背诵一堆命令,但不理解命令的执行原理、命令和文件系统的关联。本文围绕三大核心问题展开:
Linux 怎么组织文件?
↓
Shell 怎么找到并执行命令?
↓
我们如何通过命令操作文件和目录?
覆盖知识点:目录树、绝对/相对路径、PATH环境变量、alias别名、whoami 用户查看;实操命令包含 pwd/cd/ls/touch/mkdir/cp/rm/stat/man。
本篇命令在 Ubuntu、CentOS / CentOS Stream 通用;软件包管理属于发行版特有差异,后续专题单独展开。
代码仓库说明
Linux系列代码仓库已经更新,由于前期不涉及像C语言或者数据结构那样大量的代码文件,我会更新一些实际操作代码可以参考。
Linux系统编程 · Luminous/Code_2026 - 码云 - 开源中国
一、Linux 文件系统:根目录 / 与目录树模型
Windows 使用 C/D/E 盘符区分磁盘;Linux 没有盘符,全部资源挂载在唯一根目录 / 之下,整体构成一棵目录树,和数据结构中"树"模型思想完全对应。
目录树示例:
/
├── bin
├── dev
├── etc
├── home
│ └── luminous
│ ├── code
│ └── test
├── lib
├── root
├── tmp
└── usr
常见目录用途(了解即可,无需死记)
| 目录 | 简单理解 |
|---|---|
/ |
文件系统根目录 |
/home |
普通用户家目录存放位置 |
/root |
root超级用户专属家目录 |
/etc |
系统、软件配置文件 |
/bin |
基础系统命令可执行文件 |
/usr |
用户程序、库、系统资源 |
/dev |
硬件设备对应的设备文件 |
/tmp |
系统临时文件目录 |
/lib |
系统共享库 |
文件路径示例:/home/luminous/code/main.c
/
└── home
└── luminous
└── code
└── main.c
- 目录结点:
home、luminous、code,可以容纳子文件、子目录; - 普通文件:
main.c,属于树的叶子结点。
路径:定位树上结点
系统存在大量同名文件(例如多个main.c),路径用来唯一确定目录树中结点位置,分为绝对路径、相对路径。
-
绝对路径 :从根
/完整书写,和当前工作目录无关,脚本、配置文件大量使用。cd /home/luminous/code
-
相对路径 :以当前工作目录 作为起点,交互式命令行简短方便。 当前位置
/home/luminous/test,进入兄弟目录 code:cd ../code
-
三个高频特殊符号
符号 说明 .当前工作目录 ..父目录(上一级) ~当前用户家目录
./main:显式指定执行当前目录下可执行程序;cd ..:回到上一级;cd ~/cd:快速回到家目录,root用户家目录为/root。
二、Linux命令的本质:外部可执行程序 vs Shell内建命令
误区:
ls/cd不是Linux系统内置关键字,命令分为外部可执行程序 和Shell内建命令两类。
2.1 外部可执行命令
ls、cp、rm、mkdir本质是磁盘上的可执行文件。使用which查看命令对应的完整路径:
which ls
which cp
输出示例:/usr/bin/ls,Shell找到这个文件,加载运行,就实现了ls命令。
2.2 Shell内建命令 builtin
部分命令不对应磁盘上独立程序,由Shell进程自身提供实现,典型:cd、alias。
为什么
cd必须是内建:修改工作目录必须改变当前Shell进程属性;如果cd是独立子进程,子进程修改目录退出之后,父Shell工作目录完全不受影响。
使用type区分命令类型:
type cd
type ls
2.3 PATH环境变量:Shell搜索外部命令的规则
echo $PATH查看PATH环境变量,多个目录使用冒号:分隔:
echo $PATH
#示例输出:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin
PATH是Shell的搜索目录清单:输入不带路径的外部命令,Shell按顺序遍历PATH内目录,寻找匹配名字的可执行文件,找到即执行。
为什么本地编译程序需要 ./main
编译得到可执行文件main,直接输入main提示command not found,但./main可以正常运行。 原因:.(当前目录)默认不在PATH搜索列表。
main:Shell只会遍历PATH目录,不会检索当前目录;./main:显式提供路径,指定运行当前目录下main程序。
2.4 两种方式,让自己写的程序可以直接输入名字执行
-
放到PATH已存在的系统目录(如/usr/local/bin) 把编译好的
mytool复制到/usr/local/bin,之后任意目录直接输入mytool即可运行,系统目录操作一般需要管理员权限。 -
追加自定义目录到PATH环境变量 假设自己工具全部放在
/home/luminous/mybin#临时生效,仅当前shell会话
export PATH=$PATH:/home/luminous/mybin
临时export,关闭终端重新登录就失效;想要永久生效,写入
~/.bashrc配置文件,执行source ~/.bashrc重载配置,Shell配置文件后续专题详解。
三、alias命令别名:简化重复输入
alias 是Shell提供的别名机制,把长命令映射成简短别名。
#定义别名
alias ll='ls -alF'
ll并不是Linux标准原生命令,很多发行版默认预置alias。脚本编写不要依赖ll,脚本中应当写完整ls -alF。
查看别名相关命令:
alias #列出当前全部别名
alias ll #单独查看ll的定义
alias cls='clear' #自定义简短别名
四、基础实操命令集
4.1 whoami:确认当前操作用户
whoami
打印当前Shell用户身份。遇到Permission denied权限拒绝报错,第一步可以确认:我是谁。
4.2 pwd:打印当前工作目录
pwd
print working directory,输出当前位置绝对路径。
高危删除、复制操作前,优先执行
pwd && ls确认位置,避免误操作。
4.3 cd:切换目录
cd /home/luminous/code #绝对路径进入
cd .. #回到上一级
cd ~ #回家目录
cd #回家目录
cd - #最近两个目录来回切换
4.4 ls:浏览目录内容
ls #列出当前目录文件
ls -l #详细元信息
ls -a #显示以.开头的隐藏文件
ls -al #组合:全部文件+详细信息
Linux约定文件名以
.开头即为隐藏文件,例如.bashrc,ls默认不展示。
ls -l首字符代表文件类型,体现UNIX「一切皆文件」:
-普通文件;d目录;l符号链接;c字符设备;b块设备;p管道;ssocket。
4.5 touch + stat:文件创建与时间戳
touch test.txt #文件不存在:创建空文件;已存在:更新时间戳
stat test.txt #查看文件完整元数据
三个关键时间戳:
atime:文件内容访问时间;mtime:文件内容修改时间;ctime:inode元数据变更时间(不是文件创建时间,权限、属主变化会更新ctime)。
touch参数:
touch -a test.txt #更新atime
touch -m test.txt #更新mtime
touch -c test.txt #文件不存在,不新建文件,注意和-m区分
4.6 mkdir 创建目录
mkdir test
mkdir -p project/src/module/test #-p自动补齐整条多级目录链
4.7 cp 复制文件/目录
cp main.c main_backup.c #复制文件
cp main.c backup/ #复制文件到目标目录
cp -r project project_backup #-r递归:复制整棵目录子树
cp -i src.txt dst.txt #覆盖前交互提示确认
*.txt通配符是Shell提前展开,不是cp命令内部实现。
4.8 rm 删除文件/目录
rm test.txt #删除普通文件
rm -r testdir #递归删除目录(整棵子树)
rm -i test.txt #删除前交互确认,学习环境推荐
rm -rf dir #-r递归,-f强制不提示;风险极高!执行前pwd+ls确认路径
Linux没有回收站,rm删除数据很难恢复,禁止随意复制网络
rm -rf片段。
4.9 man 手册:不需要死记全部参数
man即manual,Linux自带官方文档。不止可以查询Shell命令,还可以查询系统调用、C库函数。
man手册分章节:
| 章节 | 内容 |
|---|---|
| 1 | 用户Shell命令 |
| 2 | 系统调用(系统编程重点) |
| 3 | C标准库函数 |
| 5 | 配置文件格式 |
| 7 | 协议、杂项 |
| 8 | 系统管理命令 |
示例:
man ls #查看ls命令手册
man 1 printf #shell printf命令
man 3 printf #C库printf函数
man 2 open #系统调用open,写系统编程高频使用
五、完整实操流程
whoami #确认当前用户
pwd #确认当前位置
mkdir -p linux_test/src #创建多级目录
cd linux_test/src
touch main.c test.c README.txt
ls -al
cd ..
mkdir backup
cp src/*.c backup/
# 可安装tree观察树形结构:sudo apt install tree / sudo dnf install tree
tree .
rm -r backup
man cp #忘记参数直接查手册
包管理命令属于发行版差异:Ubuntu用apt;CentOS Stream使用dnf;老版本教学CentOS使用yum;基础文件命令在两大生态完全通用。
六、核心概念梳理
Linux Shell
│
┌──────────────┴──────────────┐
│ │
Shell 内建命令 外部程序
cd / alias ls / cp / rm / gcc
│ │
│ PATH 搜索
│ │
└──────────────┬──────────────┘
│
执行命令
│
↓
Linux 文件系统
│
/
┌───────────┼───────────┐
etc home usr
│
luminous
│
project...
概念对应:
PATH:解决Shell去哪里寻找外部可执行程序;alias:简化高频重复命令输入;whoami:确认当前执行身份;pwd / ls / cd:定位、浏览、切换目录树结点;mkdir / touch:在目录树创建结点;cp / rm:复制、删除目录/子树;man:官方手册,遇到遗忘不需要全网搜索。
写在最后
本篇跳出单纯背命令,理解命令背后完整运行流程: Shell读取输入 → 判断是别名/内建命令 → 外部命令通过PATH检索可执行文件 → 运行程序操作目录树上的文件。
自己编译程序需要./main,根源就是当前目录不在PATH搜索列表中 ;想要直接输入程序名运行,要么放到PATH已有目录,要么追加自定义目录到PATH。而ll仅仅是预置别名,不是系统原生命令。
文件系统上,目录树、绝对/相对路径、. .. ~、隐藏文件,都是后续学习权限、Vim、gcc编译、Makefile的基础。