
目录Linux的软件安装的方式安装的理解什么是包管理器软件谁提供的为什么存在云服务器社区钱哪里来机器是怎么知道对应的下载链接的国外的服务器社区很多都在国外访问不了怎么办apt/yum是什么最常用命令对照表编译器和编辑器的区别编辑器vimvim 五种模式总览在命令模式下的常用快捷键视图模式下的快捷键底行模式的命令vim的配置gcc/g编译器动态链接和静态链接什么是静态链接特点什么是动态链接自动化构建make/Makefile默认顺序问题.PHONY的作用隐形问题makefie的多个版本解释说明Git理解版本控制gdb/cgdb的使用常见使用查看代码运行程序断点管理查看变量查看调用栈特殊示例条件断点只在满足条件时停下场景循环 100 次只想在第 30 次时停下。watch 监视变量变化Linux的软件安装的方式在开始的时候通常的情况下是下载到程序的源代码并进行编译得到可执行程序。但是如果是这样子去安装的话就会非常的麻烦于是有些人就把常用的软件提前编译好做成软件包放在服务器上面通过包管理器很快就能找到对应的软件包直接安装拷贝。这句是常用的yum/apt安装。因此yum/apt安装变成了最常用也是最快捷的方式。安装的理解你要安装的软件并没有你想像的那么的表面可能你会觉得就是一个软件其实他还需要安装许多依赖的库他们互相配合软件功能才能达到想要的目的因此包管理器yum/apt在安装的时候他还会自动解决你需要依赖的各种库。注意安装必须是root权限的安装到了系统里面任何人都可以使用。什么是包管理器类似手机上面的应用商店拿他就可以去搜索安装我们想要的软件。软件谁提供的为什么存在Linux 下的软件本质上是由全球程序员如 Linus、GNU 社区、各大公司为了解决自身需求而编写的源代码但这些源代码无法直接被操作系统运行需要先通过编译器如 gcc翻译成当前机器能够识别的机器码。为了让你免去手动编译的麻烦发行版维护者如 Red Hat、Ubuntu 社区会提前将这些代码在特定环境下编译好连同依赖信息一起打包成RPM 或 DEB 软件包并集中存放到软件源服务器镜像站上。当你执行yum install或apt install时包管理器就会自动连接这些服务器下载对应的软件包及其依赖并直接复制到你的系统中完成安装。之所以这套机制能免费运转是因为 Linux 生态遵循开源协议如 GPL允许自由使用和修改代码而背后的维护动力则来自技术理想、个人声誉、商业支持如红帽、Google 的资助以及生态垄断的共同驱动。云服务器社区钱哪里来维护开源软件和社区的钱主要不是靠“卖软件”赚来的而是靠“卖服务”、“卖云资源”和“大公司的战略投资”来的。1. 大公司直接掏钱养着最常见Google、Intel、IBM、Red Hat、华为、阿里巴巴这些公司专门雇了一大批工程师全职维护开源项目。为什么他们愿意掏钱因为他们的商业产品云服务器、芯片、操作系统都跑在 Linux 上。如果 Linux 有 bug、性能差、不安全他们的生意就直接受影响。所以花几千万雇人维护 Linux比花几亿去解决因为 Linux 不稳定导致的损失要划算得多。2. 卖技术支持和服务Red Hat 的经典模式软件本身免费但出了问题有人管、有赔偿、有 SLA 保证这个值钱。3. 卖云资源AWS、阿里云模式AWS 不卖 Linux但它的云服务器绝大多数跑在 Linux 上。为了让 Linux 在 AWS 上跑得更好AWS 专门养了一个团队给 Linux 内核提交优化补丁。同时AWS 提供了Amazon Linux基于 RHEL 改的发行版免费给用户用。用户用了 AWS 的 Linux自然就更愿意买 AWS 的云服务器。4. 基金会/捐款一些公司他们的系统都是使用的操作系统相关的软件很符号他们的公司开发情况因此他们回捐款维护。以上为了加深对软件安装的生态理解知道即可。机器是怎么知道对应的下载链接的操作系统内置了链接。机器知道下载链接是因为/etc/apt/sources.list里写好了“服务器地址”apt从服务器下载“软件清单Packages.gz”再从清单里找到具体软件包的.deb下载地址。国外的服务器社区很多都在国外访问不了怎么办直接回答我们并不是直接访问国外的服务器而是通过国内大学、公司搭建的“镜像站”Mirror Site来获取的。当你在国内云服务商如阿里云、腾讯云、华为云买服务器时这些云厂商默认已经把系统的软件源改成了他们自己的内网镜像地址。apt/yum是什么发行版包管理器配置文件位置CentOS / RHEL / Fedorayum或新版dnf/etc/yum.repos.d/*.repoUbuntu / Debianapt/etc/apt/sources.list它们做的事完全一样安装、卸载、更新软件自动处理依赖。Ubuntu 用aptCentOS 用yum命令稍微不同但逻辑相同。最常用命令对照表操作UbuntuaptCentOSyum更新软件列表sudo apt updatesudo yum makecache升级所有软件sudo apt upgradesudo yum update安装软件sudo apt install 软件名sudo yum install 软件名卸载软件sudo apt remove 软件名sudo yum remove 软件名搜索软件apt search 关键词yum search 关键词查看软件信息apt show 软件名yum info 软件名清理缓存sudo apt cleansudo yum clean allaptUbuntu/yumCentOS就是 Linux 的应用商店装软件用install卸软件用remove搜软件用search更新软件用update upgrade。编译器和编辑器的区别编译器和编辑器的核心区别在于功能定位编辑器是一种用于编写和修改代码或文本的工具软件如VS Code、Sublime主要提供语法高亮、自动补全、查找替换等辅助输入功能它只负责生成和保存源代码文件不执行代码而编译器是一种系统程序如GCC、Clang其作用是将人类可读的高级编程语言源代码一次性整体翻译成计算机可直接执行的机器码或中间字节码在此过程中会进行词法、语法、语义分析以及复杂的优化并输出可执行文件或目标文件。简言之编辑器是写代码的“笔”编译器是把写的代码翻译成机器能懂的“翻译官”——前者关乎文本操作后者关乎语言转换与程序构建。编辑器vimvim 是 Linux 下的文本编辑器和 Windows 里的记事本Notepad功能一样用来写代码、改配置文件。但区别是vim 完全用键盘操作没有菜单栏、没有鼠标点按钮全靠敲命令他是一个多模式编辑器。语法vim 文件名——打开vimvim主要有5种模式打开默认就是命令模式下面是vim模式的切换。vim 五种模式总览模式能做什么怎么进入① 正常模式移动光标、复制、粘贴、删除、搜索一打开 vim 就在这个模式按Esc回到这里② 插入模式输入文字打字按i、a、o等进入③ 底行模式保存、退出、查找替换、设置行号正常模式下按:④ 替换模式覆盖已有字符不新增直接盖掉正常模式下按R大写⑤ 视图模式选中/高亮文本然后批量操作正常模式下按v、V、Ctrlv在命令模式下的常用快捷键gg:快速定位到第一行shiftg:快速定位到最后一行nshiftg:快速定位到第n行shift4:定位到该光标行处的最结尾。shift6:快速定位到该光标行处的开头h,j,k,l:分别代表左下上右。默认是1个字符nh,j,k,l:分别代表左下上右移动n个字符。yy:复制该光标下的行数也可以和p进行配合粘贴(n)p:光标所在位置粘贴n行(n)w:以单词为单位向右移动n个(n)b:以单词为单位向左移动n个u撤销ctrlr:撤销u操作dd:剪切当前行或者删除如果配合p可以n剪切n行ndd:在当前行下剪切或者删除x:光标左侧不动右侧删除也可配合nx,一次性删除n个也可以和p进行配合粘贴shiftx:光标右侧不动左侧删除也可配合nx,一次性删除n个也可以和p进行配合粘贴r:替换光标所在字符nr替换n个字符shiftr:批量化替换从右到左——替换模式(功能易懂)shift~:将字母替换成大小写shift3选择光标所在的单词配合N键可以快速查找多个该单词的位置逆向查找配合shiftN正向查找。视图模式下的快捷键ctrlv进入视图模式在视图模式下进行区域的选择可以用h,j,k,lnshiftg进行定位区域shifti//esc批量化注释同理在视图模式下进行区域选择可以批量化的修改对应的内容。公式先选中要修改的区域shifti要修改的内容esc底行模式的命令shift:命令模式进入低行模式w:保存q退出set nu:设置行号set nonu:去掉行号!命令可以在不退出vim的条件下进行命令。%s/dst/src/:将det批量化变成srcvs 文件名创建/打开文件在同一目录下ctlr(按住) ww:切换窗口vim的使用技巧vim 文件名n:在打开vim的时候光标可以定位到第n行!v:可以执行最近对vim的命令操作vim的配置Vim 配置的本质就是把你在底行模式下手动敲的set nu、syntax on这类命令保存到当前用户家目录下的一个隐藏文件~/.vimrc中让 Vim 每次启动时自动读取并执行这些设置配置语法很简单用set 选项值或直接set 选项开启功能用set no选项关闭功能其中set number显示行号set tabstop4和set shiftwidth4控制缩进syntax on开启语法高亮set cursorline高亮当前行set autoindent保持自动缩进set mousea启用鼠标支持set ruler显示光标位置保存退出后重新打开 Vim所有配置自动生效让你写代码体验更好至于插件如 TagList、WinManager那是更高级的扩展等基础配置熟悉后再慢慢加。命令作用set nu开启行号set nonu关闭行号set list显示不可见字符set nolist隐藏不可见字符set paste进入粘贴模式set nopaste退出粘贴模式set mousea启用鼠标set mouse-a禁用鼠标gcc/g编译器gcc/g 是 Linux 下的 C/C 编译器作用是把人类写的.c/.cpp源代码文件翻译成计算机能执行的二进制程序。阶段输入输出做了什么① 预处理.c.i展开头文件、替换宏、去掉注释、条件编译② 编译.i.s把 C 代码翻译成汇编语言③ 汇编.s.o把汇编代码翻译成机器码目标文件④ 链接.o可执行文件合并多个.o文件和库生成最终程序gcc –E hello.c –o hello.i#预处理 gcc –S hello.i –o hello.s#编译 gcc –c hello.s –o hello.o#汇编 gcc hello.o –o hello#链接 gcc hello.c -o hello#一步到位我们写的 C 代码里printf、malloc、strlen这些函数我们只写了调用并没有写它们的实现。这些实现都在 C 标准库里libc。链接要做的就是把你的代码和这些库函数连接起来让程序运行时能找到它们。这个过程就是链接它分为动态链接和静态链接。Linux下动态库XXX.so, 静态库XXX.aWindows下动态库XXX.dll, 静态库XXX.lib动态链接和静态链接什么是静态链接原理编译时把库函数的机器码直接复制一份合并到你的可执行文件中。特点说明库文件后缀.aarchive静态库生成时机编译阶段链接时可执行文件独立运行不依赖外部库体积大每个程序都包含一份库代码内存占用大同一库被多个程序重复加载更新库更新后需要重新编译所有程序# 强制静态链接加 -static gcc -static hello.c -o hello_static # 对比大小 ls -lh hello_static # 通常好几 MB而动态链接的只有十几 KB什么是动态链接原理运行时库函数的机器码不复制到可执行文件中而是保留一个“引用”程序加载时由系统动态加载到内存多个程序共享同一份库代码。特点说明库文件后缀.soshared object共享库生成时机运行阶段程序加载时可执行文件依赖外部库缺库无法运行体积小不包含库代码内存占用小多个程序共享同一份库更新库更新后程序无需重新编译对比维度静态链接动态链接库文件后缀.a静态库.so动态库/共享库复制时机编译时复制库代码运行时加载库代码可执行文件大小大库代码全包进去小只有引用不包含库是否独立运行是不依赖外部否系统里必须有所需的.so内存占用高每个进程各有一份低多个进程共享同一份.so磁盘占用高每个程序都包了一份库低所有程序共用一份.so库更新需要重新编译整个程序不需要重编译只更新.so即可启动速度快已全部加载稍慢需要加载.sogcc 默认不是默认目标: 依赖 命令是默认常见例子嵌入式程序、Go 编译的静态二进制大多数 Linux 程序ls、gcc、nginx自动化构建make/Makefile概念Makefile 是一份“编译说明书”告诉make命令怎么编译和链接程序。make是执行这个说明书的命令。如果不写Makefile那么每次都要在命令行上面写入一大串指令很麻烦。格式目标: 依赖 命令用vim写了Makefile和myproc.c文件217 updates can be applied immediately. hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ ll total 16 drwxrwxr-x 2 hzx hzx 4096 Sep 7 22:36 ./ drwxrwxr-x 5 hzx hzx 4096 Sep 4 14:53 ../ -rw-rw-r-- 1 hzx hzx 0 Sep 7 22:36 code.c -rw-rw-r-- 1 hzx hzx 74 Sep 4 15:04 Makefile -rw-rw-r-- 1 hzx hzx 78 Sep 11 16:56 myproc.c hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ cat Makefile myproc:myproc.c gcc -o myproc myproc.c .PHONY:clean clean: rm -f myproc hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ cat myproc.c #includestdio.h int main() { printf(hello Linux\n); return 0; } hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$具体操作#预处理编译汇编链接一次性 hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ make gcc -o myproc myproc.c #看到生成了执行文件myproc* hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ ll total 32 drwxrwxr-x 2 hzx hzx 4096 Sep 11 17:19 ./ drwxrwxr-x 5 hzx hzx 4096 Sep 4 14:53 ../ -rw-rw-r-- 1 hzx hzx 0 Sep 7 22:36 code.c -rw-rw-r-- 1 hzx hzx 74 Sep 4 15:04 Makefile -rwxrwxr-x 1 hzx hzx 15960 Sep 11 17:19 myproc* -rw-rw-r-- 1 hzx hzx 78 Sep 11 16:56 myproc.c #执行 hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ ./myproc hello Linux #清除可执行文件 hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ make clean rm -f myproc hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ ll total 16 drwxrwxr-x 2 hzx hzx 4096 Sep 11 17:20 ./ drwxrwxr-x 5 hzx hzx 4096 Sep 4 14:53 ../ -rw-rw-r-- 1 hzx hzx 0 Sep 7 22:36 code.c -rw-rw-r-- 1 hzx hzx 74 Sep 4 15:04 Makefile -rw-rw-r-- 1 hzx hzx 78 Sep 11 16:56 myproc.cmake:是一个命令工具Makefile一个文本文件里面写了“编译说明书”。如果这个所谓的编译说明说的名字不是GNUmakefile,makefile,Makefile这些那么就不可以直接make而是需要make -f文件名默认情况下就是直接上面的三种情况。默认顺序问题输入make命令的时候执行的是gcc -o myproc myproc.c执行rm的时候为什么命令输入的是make clean如果把顺序换一下可以发现输入make执行的是clean命令输入make myproc的执行的是gcc命令。因此得出结论make命令扫描makefile的时候默认选择第一个目标文件make clean指定了目标是clean那么执行的就是rm。.PHONY的作用把某个目标声明为“伪目标”让 make 每次都执行它而不是去检查有没有同名文件。如果不加PHONY直接去make的时候他会检查有没有同名文件看看他是不是最新的如果是最新的make就没有作用了。问题怎么知道文件时最新的hzxVM-0-12-ubuntu:~/notes/lesson_develop_tool$ stat myproc File: myproc Size: 15960 Blocks: 32 IO Block: 4096 regular file Device: 253,2 Inode: 657303 Links: 1 Access: (0775/-rwxrwxr-x) Uid: ( 1003/ hzx) Gid: ( 1003/ hzx) Access: 2026-09-11 18:28:27.396038061 0800 Modify: 2026-09-11 18:28:25.715921632 0800 Change: 2026-09-11 18:28:25.716921701 0800 Birth: 2026-09-11 18:28:25.700920592 0800因为文件内容属性。上面有三个时间Access、Modify和Change时间英文含义什么时候更新Accessatime文件被读取的时间执行cat、less、grep等读取操作时Modifymtime文件内容被修改的时间执行echo、vim、等写入操作时Changectime文件属性被修改的时间修改权限、所有者、文件名等属性时隐形问题如果多次的cat查找文件的内容这个使时间的属性Access可能不变因为会造成大量的I/O操作具体多久更新一次和特定的领域有关重新回答.PHONY的是怎么知道是最新的——根据Modify的时间。修改的时间不变那么编译就没有必要多次去make了。makefile推导基本规则makefie的多个版本解释说明makefile单文件BINmyproc # 最终生成的可执行文件名 CCgcc # 使用的编译器 SRCmyproc.c # 源文件名 FLAGS-o # 编译选项-o 表示指定输出文件名 RMrm -f # 删除命令-f 表示强制删除不提示 ##$(BIN):$(SRC) ##$(CC) $(FLAGS) $(BIN) $(SRC) $(BIN):$(SRC) $(CC) $(FLAGS) $ $^ .PHONY:clean clean: $(RM) $(BIN) .PHONY:test test: echo $(BIN) echo $(CC) echo $(SRC) echo $(FLAGS) echo $(RM)makefile多文件BINproc.exe # 最终生成的可执行文件名 CCgcc # 编译器 SRCmyproc.c # 源文件 OBJmyproc.o # 目标文件编译后生成的中间文件 LFLAGS-o # 链接选项-o 指定输出文件名 FLAGS-c # 编译选项-c 只编译不链接 RMrm -f # 删除命令 $(BIN):$(OBJ) $(CC) $(LFLAGS) $ $^ echo linking ... $^ to $ %.o:%.c $(CC) $(FLAGS) $ echo compiling ... $ to $ .PHONY:clean clean: $(RM) $(OBJ) $(BIN)BINproc.exe # 最终可执行文件 CCgcc # 编译器 #SRC$(shell ls *.c) # 注释掉的旧写法 SRC$(wildcard *.c) # 新写法自动获取所有 .c 文件 OBJ$(SRC:.c.o) # 将 SRC 中的 .c 替换为 .o LFLAGS-o # 链接选项 FLAGS-c # 编译选项 RMrm -f # 删除命令 $(BIN):$(OBJ) $(CC) $(LFLAGS) $ $^ echo linking ... $^ to $ %.o:%.c $(CC) $(FLAGS) $ echo compiling ... $ to $ .PHONY:clean clean: $(RM) $(OBJ) $(BIN)部分作用$(wildcard *.c)自动收集所有.c文件$(SRC:.c.o)把.c列表转换成.o列表链接规则把所有.o链接成可执行文件编译规则把每个.c编译成.oclean删除生成的文件test打印变量值调试用$目标名$^所有依赖$第一个依赖不显示命令本身GitGit 是版本控制器用来记录代码的每一次修改让你可以随时回退到任意历史版本也方便多人协作。理解版本控制版本控制就是记录文件每一次修改的工具让你可以随时查看历史、回退到任意版本。git add# 添加单个文件 git add myproc.c # 添加所有改动 git add . # 添加所有 .c 文件 git add *.cgit commit# 提交并写说明 git commit -m 修复了编译错误 # -m 后面是提交日志描述这次改了什么git push# 推送到远程仓库 git push # 第一次推送可能需要指定分支 git push -u origin main安装# Ubuntu sudo apt install -y git # CentOS sudo yum install -y git # 验证 git --version完整流程在gitee上新建仓库复制链接在相关的路径下执行命令克隆到本地git clone https://github.com/你的用户名/myproject.git cd myprojectmyproject/ ├── .git/ ← 隐藏目录Git 的“数据库” ├── .gitignore ← 文本文件告诉 Git 忽略哪些文件 ├── myproc.c ← 你的源代码 ├── Makefile ← 你的编译脚本 └── README.md ← 仓库说明hzxVM-0-12-ubuntu:~/myproject$ cp ~/notes/lesson_develop_tool/myproc.c . hzxVM-0-12-ubuntu:~/myproject$ cp ~/notes/lesson_develop_tool/Makefile . hzxVM-0-12-ubuntu:~/myproject$ git add . hzxVM-0-12-ubuntu:~/myproject$ git commit -m 添加 myproc.c 和 Makefile #commit后面的内容不能胡写要说明修复了什么问题 hzxVM-0-12-ubuntu:~/myproject$ git push注意假设两个程序员A 和 B同时修改了同一个文件的同一行A 先git push成功B 后git push时Git 发现“你修改的这行在远程仓库已经被别人改过了我不确定该保留谁的。”所以要先gie pull把远端的仓库和本地仓库再做一次同步再用三板斧。gdb/cgdb的使用按照之前的模式编译的时候一般都是gcc -o 源文件 目标文件但是他默认没有调试功能因此要有调试功能就要再命令的后面 -g这样才是debug模式。由于gdb的页面比较恶心所以一般使用cgdb但是他的工作内容信息是一模一样的。但是要安装Ubuntu: sudo apt-get install -y cgdbCentos: sudo yum install -y cgdb常见使用格式cgdg 可执行程序名cgdb myprocctrl d/quit退出查看代码命令作用示例list/l显示源代码默认 10 行llist 10/l 10显示第 10 行附近的代码l 10list 函数名/l 函数名显示指定函数的源码l mainlist 文件名:行号显示指定文件的源码l mycmd.c:1(gdb) l # 显示当前行附近的 10 行 (gdb) l 20 # 显示第 20 行附近的代码 (gdb) l main # 显示 main 函数的代码 (gdb) l mycmd.c:1 # 显示 mycmd.c 第 1 行附近的代码运行程序命令作用示例run/r从程序开头连续执行rrun 参数带参数运行r arg1 arg2continue/c从当前位置继续执行cuntil 行号执行到指定行号until 20finish执行到当前函数返回finish(gdb) r # 从头运行程序 (gdb) r input.txt # 带参数运行 (gdb) c # 继续执行到下一个断点 (gdb) until 20 # 执行到第 20 行 (gdb) finish # 执行完当前函数返回到调用处命令作用示例next/n单步执行不进入函数内部逐过程nstep/s单步执行进入函数内部逐语句s断点管理命令作用示例break 行号在指定行设置断点break 10break 文件名:行号在指定文件的指定行设断点break test.c:10break 函数名在函数开头设断点break maininfo breakpoints/i b查看所有断点i bdelete breakpoints/d删除所有断点ddelete breakpoints n删除序号为 n 的断点d 1disable breakpoints禁用所有断点disableenable breakpoints启用所有断点enablecondition n 条件给断点 n 加条件condition 1 i30注意只有打断点的时候是更加代码行号打如果有了断点对其进行操作一般都是根据编号。查看变量命令作用示例print 变量/p 变量打印变量的值p xprint 表达式打印表达式结果p startendset var 变量值修改变量的值set var i10display 变量每次停止时自动显示变量display xundisplay 编号取消自动显示undisplay 1info locals/i locals查看当前栈帧的局部变量i locals查看调用栈命令作用示例backtrace/bt查看当前调用栈btframe n切换到第 n 层栈帧frame 2info frame查看当前栈帧详细信息info frame特殊示例条件断点只在满足条件时停下场景循环 100 次只想在第 30 次时停下。(gdb) b 9 if i 30 # 在第 9 行设条件断点 (gdb) r (gdb) p i # 此时 i 30给已有断点加条件(gdb) b 9 # 先设普通断点 (gdb) condition 2 i30 # 给 2 号断点加条件watch 监视变量变化(gdb) watch result # 监视 result 变量 (gdb) c # 当 result 值变化时GDB 会停下来并提示 Hardware watchpoint 2: result Old value 0 New value 1