Important
我所观看的是B站一位名叫“爱编程的大丙”的讲解,这是他的个人博客:https://subingwen.cn/),本文的整理大部分都来自于它的博客。
大部分内容都可以在互联网上轻易搜索到,只是为了加强记忆而整理
目录
- Linux系统简介
- 文件管理命令
- 用户管理命令
- 压缩命令
- 查找命令
- Vim 的使用
- gcc/g++
- 静态库和动态库制作和使用
- Makefile
- GDB 调试
Linux系统简介
1991年,GNU计划已经开发出了许多工具软件,最受期盼的GNU C编译器已经出现。GNU的操作系统核心HURD一直处于实验阶段(GNU工程从1984年起就在做这件事),没有任何可用性,实质上也没能开发出完整的GNU操作系统。也是这一年,Linux诞生了。Linux是UNIX操作系统的一个克隆系统,但是Linux是开源的。那时候它只是一个系统内核,没有与之配套的应用软件。这时候Linux和GNU一拍即合,就有了我们现在使用的操作系统。GNU奠定了Linux用户基础和开发环境。(GNU 是 GNU's Not Unix 的递归缩写,是一种口号,最早由 Richard Stallman 呼吁并倡导的,号召软件自由。)
Linux时间线
- 1991年初:林纳斯·托瓦兹开始在一台386sx兼容微机上学习minix操作系统。
- 1991年4月:林纳斯·托瓦兹开始酝酿并着手编制自己的操作系统。
- 1991年4月13日:在comp.os.minix上发布说自己已经成功地将bash移植到了minix上,而且已经爱不释手、不能离开这个shell软件了。
- 1991年10月5日:林纳斯·托瓦兹在comp.os.minix新闻组上发布消息,正式向外宣布Linux内核的诞生。
- 1992年:Linux与其他GNU软件结合,完全自由的操作系统正式诞生。该操作系统往往被称为“GNU/Linux”。
- 1993年:大约有100余名程序员参与了Linux内核代码编写/修改工作,其中核心组由5人组成。此时Linux 0.99的代码大约有十万行,用户大约有10万左右。
- 1994年3月:Linux1.0发布,代码量17万行。当时是按照完全自由免费的协议发布,随后正式采用GPL协议。
Linux发行版
官方每年会发布两个Linux版本,每个版本的版本号由两部分组成:主版本号 + 副版本号。
- 主版本号为当年年份,长期支持版的年份为偶数,测试版年份为奇数。
- 副版本号为月份,在4月份发布的为相对稳定版,在10月份发布的为测试版。
因此应当选择主版本号为偶数,副版本号为04的版本,进行安装使用。
Linux内核
Linux系统从应用角度来看,分为内核空间和用户空间两个部分。内核空间是Linux操作系统的主要部分,但是仅有内核的操作系统是不能完成用户任务的。丰富并且功能强大的应用程序包是一个操作系统成功的必要条件。
Linux内核主要由五个子系统组成:进程调度、内存管理、虚拟文件系统、网络接口和进程间通信。以下是对每个子系统的详细描述:
-
进程调度是Linux内核的核心功能之一,它负责管理系统中所有进程的运行状态和资源分配。进程调度的主要任务是确保所有进程能够公平地使用CPU资源,同时满足实时性要求。Linux支持三种调度策略:SCHED_OTHER、SCHED_FIFO和SCHED_RR。SCHED_OTHER是默认的分时调度策略,适用于普通进程,通过时间片轮转的方式让所有进程公平地使用CPU资源。SCHED_FIFO是一种实时调度策略,采用先进先出的方式,优先级高的进程会一直运行,直到主动放弃CPU或被更高优先级的进程抢占。SCHED_RR与SCHED_FIFO类似,但同一优先级的实时进程之间采用时间片轮转,防止某个进程长时间独占CPU。实时调度策略通常只允许root用户设置,以防止普通用户进程影响系统稳定性。
-
内存管理是Linux内核的另一个重要子系统,它通过虚拟内存技术实现了多个进程之间的内存共享和隔离。虚拟内存将物理内存与进程实际可用的内存空间分离,每个进程都拥有独立的虚拟地址空间。操作系统通过内存管理单元(MMU)将虚拟地址映射到实际的物理内存地址,从而提高了系统的安全性和稳定性。虚拟内存的大小通常远大于实际物理内存,操作系统会将暂时不用的数据存放到硬盘上的交换空间(swap),当需要时再调回物理内存。这种机制允许更多程序同时运行,提高了资源利用率。
-
虚拟文件系统(VFS)是Linux内核中的一个抽象层,用于屏蔽不同文件系统之间的差异,为用户和应用程序提供统一的文件操作接口。VFS的存在使得Linux能够同时支持多种文件系统,例如ext4、NTFS和FAT等。通过VFS,开发者可以在不关心底层文件系统实现的情况下,使用统一的API进行文件操作。VFS还提高了系统的兼容性和扩展性,使得Linux可以轻松添加对新文件系统的支持。此外,VFS的灵活性也让文件系统的开发和维护变得更加简单。
-
网络接口是Linux内核的重要组成部分,它支持多种网络协议和设备驱动程序,使得Linux能够在各种网络环境中运行。网络接口分为网络协议和驱动程序两部分,网络协议定义了数据传输的通信标准,而驱动程序则负责与硬件设备的交互。Linux支持的网络设备种类繁多,几乎涵盖了所有主流的网络硬件。通过强大的网络接口支持,Linux在服务器、路由器和嵌入式设备等领域得到了广泛应用。
-
进程间通信(IPC)是Linux内核提供的另一项关键功能,它允许多个进程之间进行数据交换和协作。Linux继承了UNIX系统的IPC机制,支持多种通信方式,包括管道、信号、消息队列、共享内存和套接字。管道是一种半双工通信方式,适用于具有亲缘关系的进程;信号是一种异步通信机制,用于通知进程发生了某种事件;消息队列允许进程以消息为单位进行通信,支持随机读写和消息优先级;共享内存是最快的IPC方式,允许多个进程直接访问同一块物理内存区域;套接字则支持本地和网络进程间的通信,是网络编程的基础。通过这些多样化的通信方式,Linux能够高效地支持复杂的多进程应用。
Linux目录
与Windows下的文件组织结构不同,Linux不使用磁盘分区符号来访问文件系统,而是将整个文件系统表示成树状的结构。Linux系统每增加一个文件系统都会将其加入到这个树中。操作系统文件结构的开始,只有一个单独的顶级目录结构,叫做根目录。所有一切都从“根”开始,用“/”代表,并且延伸到子目录。Linux则通过“挂接”的方式把所有分区都放置在“根”下各个目录里。
在Linux中根目录的子目录结构相对是固定的(名字固定),不同的目录功能也是固定的。
| 目录 | 功能描述 |
|---|---|
| bin | binary,二进制文件目录,存储了可执行程序。常用的命令对应的可执行程序都在这个目录中。 |
| sbin | super binary,root用户使用的一些二进制可执行程序。 |
| etc | 配置文件目录,系统的或者用户自己安装的应用程序的配置文件都存储在这个目录中。 |
| lib | library,存储了一些动态库和静态库,给系统或者安装的软件使用。 |
| media | 挂载目录,挂载外部设备,比如:光驱、扫描仪。 |
| mnt | 临时挂载目录,比如我们可以将U盘临时挂载到这个目录下。 |
| proc | 内存使用的一个映射目录,给操作系统使用的。 |
| tmp | 临时目录,存放临时数据,重启电脑数据就被自动删除了。 |
| boot | 存储了开机相关的设置。 |
| home | 存储了普通用户的家目录,家目录名和用户名相同。 |
| root | root用户的家目录。 |
| dev | device,设备目录。Linux中一切皆文件,所有的硬件会抽象成文件存储起来,比如:键盘、鼠标。 |
| lost+found | 一般时候是空的。电脑异常关闭/崩溃时用来存储这些无家可归的文件,用于用户系统恢复。 |
| opt | 第三方软件的安装目录。 |
| var | 存储了系统使用的一些经常会发生变化的文件,比如:日志文件。 |
| usr | unix system resource,系统的资源目录。 |
| /usr/bin | 可执行的二进制应用程序。 |
| /usr/games | 游戏目录。 |
| /usr/include | 包含的标准头文件目录。 |
| /usr/local | 和opt目录作用相同,安装第三方软件。 |
命令解析器
在Linux中,命令解析器(通常称为shell)是用户与操作系统交互的重要桥梁。shell是一个进程,负责解析并执行用户在终端输入的命令。Linux默认使用bash(Bourne Again SHell)作为命令解析器,它是sh的增强版,支持命令行编辑、历史记录和自动补全等功能。此外,Linux还支持其他类型的shell,如zsh和csh,用户可以根据需求切换使用。
当用户在终端输入命令并按下回车键时,shell会启动一系列流程。首先,它读取用户输入的内容,并判断是内部命令(如cd、exit)还是外部命令(如ls、cat)。对于外部命令,shell会根据PATH环境变量中指定的目录,依次查找对应的可执行文件。如果找到,shell会创建一个新进程运行该程序,并将结果返回到终端;如果未找到,则提示“命令未找到”。
shell不仅能执行单条命令,还支持命令组合、管道、重定向、变量和脚本编程等强大功能。用户还可以通过修改PATH变量,添加自定义命令路径,实现个性化的命令环境。这种机制类似于Windows中的Path变量,极大地方便了软件的调用和管理,提高了操作效率。例如,在终端输入ls时,shell会在PATH目录中查找ls命令的可执行文件(通常在/bin/ls),找到后执行并显示结果;而输入不存在的命令时,则会提示错误信息。
命令行快捷键
在命令行输入一些指令的时候,经常需要移动光标,或者删除一些字符。对应的一些快捷键操作如下表:
| 快捷键 | 功能 | 备注 |
|---|---|---|
| Tab | 命令自动补齐 | |
| Ctrl+p | 显示输入的上一个历史命令 | 也可以使用↑键 |
| Ctrl+n | 显示输入的下一个历史命令 | 也可以使用↓键 |
| Ctrl+a | 光标移动到命令行首 | 也可以使用Home键 |
| Ctrl+e | 光标移动到命令行尾 | 也可以使用End键 |
| Ctrl+u | 删除光标前的部分字符串 | |
| Ctrl+k | 删除光标后的部分字符串 | |
| → | 光标向右移动一个字符 | |
| ← | 光标向左移动一个字符 | |
| Backspace/Delete | 删除光标前/后的一个 |
关于Tab的补充:
由于很多shell命令的开头字母是相同的,在这种情况下,按一次Tab是不会自动补齐的。我们可以连续按两次Tab键,在当前终端中就可以显示出所有匹配成功的shell命令。为了能够快速补全shell指令,我们可以多输入一些前缀字符之后,再按Tab键。
文件管理命令
cd(Change Directory)
- 切换目录:
cd 目录名 - 上级目录:
cd .. - 当前目录:
cd . - 家目录:
cd或cd ~或cd /home/用户名 - 上次目录:
cd -
ls(List)
- 查看目录/文件:
ls [参数] [目录|文件] - 显示所有(含隐藏):
ls -a - 详细信息:
ls -l - 人类可读大小:
ls -lh - 目录后缀:
ls -F - 文件类型:
-普通,d目录,l软链,c字符设备,b块设备,p管道,s套接字 - 权限:
r读,w写,x执行,-无
| 参数 | 英文全称 | 含义说明 |
|---|---|---|
| -a | --all | 显示所有文件(含隐藏文件) |
| -l | --long | 以详细信息列表显示 |
| -h | --human-readable | 以人类可读方式显示文件大小 |
| -F | --classify | 在目录等后加上类型标记符号 |
| -d | --directory | 仅显示目录本身而非内容 |
| -R | --recursive | 递归显示子目录内容 |
| -S | --sort=size | 按文件大小排序 |
| -t | --sort=time | 按修改时间排序 |
| -r | --reverse | 反向排序 |
| -i | --inode | 显示文件的 inode 号 |
| -s | --size | 显示文件大小(块数) |
| -A | --almost-all | 显示除 . 和 .. 以外的所有文件 |
| -G | --no-group | 不显示组信息 |
| -1 | 每行只显示一个文件名 |
mkdir / rm(Make Directory / Remove)
- 创建目录:
mkdir 目录名,多级:mkdir -p parent/child - 删除空目录:
rmdir 目录名 - 递归删除:
rm -r 目录名 - 强制/提示:
rm -f/rm -i
| 命令 | 参数 | 英文全称 | 含义说明 |
|---|---|---|---|
| mkdir | -p | --parents | 递归创建多级目录 |
| rm | -r | --recursive | 递归删除目录及内容 |
| rm | -f | --force | 强制删除,不提示 |
| rm | -i | --interactive | 删除前进行确认 |
| rmdir | 删除空目录 |
cp(Copy)
- 拷贝文件:
cp 源 目标 - 拷贝目录:
cp -r 源目录 目标目录
| 命令 | 参数 | 英文全称 | 含义说明 |
|---|---|---|---|
| cp | -r | --recursive | 递归复制目录及其内容 |
| cp | -a | --archive | 归档模式,等同于 -dR --preserve=all |
| cp | -f | --force | 强制覆盖已存在的目标文件 |
| cp | -i | --interactive | 覆盖前进行确认 |
| cp | -u | --update | 只复制源文件比目标文件新的或目标文件不存在的文件 |
| cp | -v | --verbose | 显示复制过程 |
| cp | -p | --preserve | 保留文件属性 |
| cp | -b | --backup | 覆盖前先备份目标文件 |
| cp | -d | --no-dereference | 不跟随符号链接 |
| cp | -l | --link | 对源文件建立硬链接而非复制 |
| cp | -s | --symbolic-link | 对源文件建立符号链接而非复制 |
注:cp -a(或 --archive)的应用场景主要是需要完整复制目录结构和文件属性时使用,确保目标目录与源目录在内容和属性上保持一致。常见于备份、迁移数据等操作。
mv(Move/Rename)
- 移动:
mv 源 目标目录 - 重命名:
mv 原名 新名 - 覆盖:
mv 文件A 文件B(A覆盖B)
| 命令 | 参数 | 英文全称 | 含义说明 |
|---|---|---|---|
| mv | -f | --force | 强制覆盖已存在的目标文件 |
| mv | -i | --interactive | 覆盖前进行确认 |
| mv | -n | --no-clobber | 不覆盖已存在的目标文件 |
| mv | -u | --update | 只移动比目标文件新的或目标文件不存在的文件 |
| mv | -v | --verbose | 显示移动过程 |
| mv | -b | --backup | 覆盖前先备份目标文件 |
| mv | -t | --target-directory | 指定目标目录 |
| mv | -T | --no-target-directory | 把目标视为普通文件 |
注:mv -T(或 --no-target-directory)的应用场景主要是防止目标是目录时发生“移动到目录下”这种行为,而是强制把目标当作普通文件名处理。常见于脚本或自动化操作,确保行为一致、可控。
查看文件内容
- 全部显示:
cat 文件 - 分页:
more 文件或less 文件 - 前N行:
head -n N 文件 - 后N行:
tail -n N 文件
| 命令 | 参数 | 英文全称 | 含义说明 |
|---|---|---|---|
| cat | 无 | concatenate | 连接并显示文件内容 |
| more | 无 | more | 分页显示文件内容 |
| less | 无 | less | 分页显示文件内容(可前后翻页) |
| head | -n | --lines | 显示文件的前N行 |
| tail | -n | --lines | 显示文件的后N行 |
| tail | -f | --follow | 实时输出文件新增内容 |
注:tail -f 的典型应用场景是实时查看文件内容的新增部分,常用于监控日志文件的最新输出。
链接
- 软链接:
ln -s 源 软链接名 - 硬链接:
ln 源 硬链接名(目录不可用)
| 命令 | 参数 | 英文全称 | 含义说明 |
|---|---|---|---|
| ln | -s | --symbolic | 创建符号链接(软链接) |
| ln | 无 | 无 | 创建硬链接(默认行为) |
注:软链接 ≈ Windows“快捷方式”,指向路径,原文件删了就失效;硬链接 是同一个文件的多个名字,原文件删了数据还在,和 Windows 快捷方式不同。
软链接常用于需要跨目录、跨分区引用文件的场景;硬链接常用于需要多个名字访问同一数据的场景。硬链接(Hard Link)是对同一个文件内容的另一个引用(指向同一个 inode)。删除原文件,硬链接依然可以访问数据,只有所有硬链接都删除后,文件才真正被删除。
文件属性
- 权限(符号法):
chmod who [+|-|=] mod 文件 - 权限(数字法):
chmod nnn 文件 - 改所有者:
sudo chown 用户 文件或sudo chown 用户:组 文件 - 改组:
sudo chgrp 组 文件
| 命令 | 参数 | 英文全称 | 含义说明 |
|---|---|---|---|
| chmod | who, [+ | - | =], mod |
| chmod | nnn | 无 | 数字法修改权限(如 755, 644) |
| chown | 无 | change owner | 更改文件所有者 |
| chown | : | 更改文件所属组(与用户一起用) | |
| chgrp | 无 | change group | 更改文件所属组 |
其他常用命令
- 树状目录:
tree [-L n] [目录] - 当前目录:
pwd - 创建空文件/更新时间:
touch 文件 - 查命令路径:
which 命令 - 输出重定向:
命令 > 文件(覆盖),命令 >> 文件(追加)
| 命令 | 参数 | 英文全称 | 含义说明 |
|---|---|---|---|
| tree | -L n | level, --max-depth=n | 限制显示目录层级 |
| pwd | 无 | print working directory | 显示当前工作目录 |
| touch | 无 | 无 | 创建空文件或更新时间戳 |
| which | 无 | 无 | 显示命令的可执行文件路径 |
| > | 无 | 无 | 输出重定向(覆盖) |
| >> | 无 | 无 | 输出重定向(追加) |
用户管理命令
用户切换
Linux 是多用户操作系统,可以同时登录多个用户。常见用户切换命令如下:
- 切换用户:
su 用户名- 只切换用户,工作目录不变。
- 切换用户并切换到家目录:
su - 用户名- 切换用户,同时进入该用户的家目录。
- 返回上一个用户:
exit
添加与删除用户
- 添加用户:
sudo adduser 用户名- 有些 Linux 发行版会提示设置密码和用户信息,有些则直接创建。
- 新用户家目录会自动创建在
/home/用户名,可通过切换用户或查看/etc/passwd文件验证。
- 删除用户:
sudo userdel 用户名- 删除用户但保留家目录。
- 删除用户并删除家目录:
sudo userdel -r 用户名 - 使用
deluser命令(部分发行版支持):sudo deluser 用户名只删除用户,不删除家目录。- 若需删除家目录,需手动执行:
sudo rm -r /home/用户名 - CentOS 通常只支持
userdel,Ubuntu 支持userdel和deluser。
用户组管理
- 添加用户组:
sudo groupadd 组名 - 删除用户组:
sudo groupdel 组名 - 用户组信息可在
/etc/group文件中查看。
密码管理
- 修改当前用户密码:
passwd - 管理员修改其他用户密码:
sudo passwd 用户名 - 管理员修改 root 密码:
sudo passwd root
注意事项:
- 普通用户默认没有使用
sudo的权限,需管理员授权。 - 授权普通用户执行管理员命令存在安全风险,实际工作中需谨慎操作。