Linux 基本工具

1. yum 包管理器

  • 安装软件的方式:

    • 源代码安装(不推荐)

    • rpm 包安装:安装的本质,就是把可执行程序拷贝到指定的路径下即可(最基本的理解)

      不推荐,因为软件包不好找,并且软件包之间存在依赖关系,可能安装完成之后无法运行

    • yum 一键式安装:把软件所有的依赖打包好一块下载,类似于一个应用商店,软件存放在远端的 yum 服务器上。

      可知 yum 中含有有关文件下载路径的配置。

      镜像源:把被 GFW 禁止访问的网站资源复制一份,到国内的网站上方便大家下载。

  • yum 命令:

    • yum list | grep <文件名> 列出所有包含文件名的软件

    • yum install [options] <软件名> 下载对应软件

    • yum remove [options] <软件名> 删除对应软件

      选项:

      • -y 下载/删除过程中的交互全部同意

    关于软件源:

    • ls /etc/yum.repos.d/ 命令查看文件,CentOS-Base 表示基础软件源,CentOS-Epel 表示扩展软件源。

    • 更新软件源:把原来的软件源(主要在 CentOS-Base 中)更换为新的软件源,如阿里云镜像,网易云镜像,清华大学 tuna 镜像等。

2. Vim

  • vi/vim:就是一款文本编辑器,类似于 Notepad++,不具有代码编译功能

    vim 也是一款多模式的编辑器,有 8 ~ 12 种模式

    vim 常见模式:

    • 命令模式 - 打开时默认的模式

    • 底行模式 - 退出文件/调出行号

    • 插入(编辑)模式 - 写入

    Windows 编写代码一般在 VS,CLion,DevC++ 等集成开发环境(IDE,Integrated Development Environment)下,能够以图形化界面方式调用 gcc/g++ 编译代码。

  • yum 模式转换:

    • 命令模式进入插入模式:按 a / i / o,三种做法有不同效果:

      • 输入 i,直接进入插入模式

      • 输入 a,进入插入模式,同时光标向后移动一格

      • 输入 o,进入插入模式,同时光标向下移动一行

    • 插入模式进入命令模式:按 Esc 即可

      重复多次按 Esc,最后一定会回到命令模式。

    • 底行模式和插入模式之间无法直接互换

    • 命令模式进入底行模式:shift + ;,也就是 :

    • 底行模式进入命令模式:Esc

  • 底行模式命令:

    • w - 保存

    • q - 退出

    • wq - 保存并退出

    • w! - 强制保存

    • q! - 强制退出

    • wq! - 强制保存并强制退出

    • set nu[mber] - 调出行号

    • set nonu - 取消行号

    • !<命令> - 在不退出 vim 的情况下,直接运行系统命令(查看,编译,运行)

    • /<关键字> - 搜索文件中的关键字

      n 跳转到下一个匹配项。

  • 命令模式:解决在没有鼠标的情况下如何选择,移动光标和复制,拷贝代码段

    光标操作命令:

    • 快速移动到代码最开始:gg

    • 快速移动光标到最后一行:shift + g,也就是 G

    • 定位光标到第 n 行:n + shift + g

    • 快速定位光标到该行最右侧:shift + 4,也就是 $

    • 快速定位光标到该行最左侧:shift + 6,也就是 ^

      上面的两个符号也叫做"锚点符号"。

    • 光标上下左右移动:h 左移,l 右移,j 下移,k 上移

    • 光标移动到该行的第 x 个字符:x l

    • 光标以单词为单位向后/前移动,支持跨行:w b

      如果识别不到单词,就按照字符格式一个个往后走。

    • 复制光标所在行[和下面的 n - 1 行]:[n] yy

    • 复制光标所在单词[和后面 n - 1 个单词]:[n] yw

    • 粘贴[ n 次]内容到当前行的下一行:[n] p

    • 撤销刚刚的操作:u

    • 撤销刚才的撤销操作(恢复):CTRL + R

    • 剪切光标所在行[和下面的 n - 1 行]:[n] dd

      tips:也可以删除用。

    • 文本大小写互相转换:shift + `,按一次转换一个字母

    • (用同一个字符)替换光标所在处的字符[和后面 n - 1 个字符]:[n] r <新字符>

    • 删除光标所在处的字符[和后面 n - 1 个字符]:[n] x,敲一下删除一次

    • 删除光标所在处的前一个字符[和前面 n - 1 个字符]:[n] shift + x,也就是 X

    • 查找和光标所在单词完全一致的单词:shift + 3,也就是 #,按 n 跳转到下一个匹配项

      vim 默认情况下可以打开不存在的文件,除非直接退出,否则退出之后就会生成该文件。

  • new 替换模式:命令模式 shift + r 进入,也就是 R,返回命令模式 Esc

    直接替换光标中的字符

  • new 视图模式:命令模式 CTRL + v 进入,返回命令模式 Esc

    • 批量化注释:进入视图模式后,用 j k 调整下/上来选中区域,然后 shift + i (I) 进入插入模式,再输入两条斜杠 //,最后 Esc 退出即可

    • 批量化删除注释:h j k l 选中区域,然后 d 删除

  • vim 也支持多文件编辑:底行模式下 vs <新文件名> 能分屏浏览新的文件

    • 光标在哪,就是在编写哪个文件

    • 切换窗口:CTRL + ww

    • 底行模式的指令跟随光标,光标在哪,底行命令就对哪个文件生效

    • 多个窗口的文件内容可以互相复制粘贴

  • 小技巧:

    • vim 带有记忆功能,上次编辑在哪行退出,再重新进入就是哪行

    • 让 vim 进入时光标挪动到第 x 行:vim <文件名> +x

  • vim 的配置:

    • 基础配置:初步理解 vim 配置的原理

      • .vimrc 文件里包含的指令在打开 vim 时,会自动生效

      • 配置 vim,本质就是向 .vimrc 文件中写入更多的指令

        .vimrc 文件中,可以用 " 来注释一行

      • vim 可能会需要各种插件来补充功能

    • 直接自动化部署配置

3. gcc / g++

默认用 gcc 用来编译 .c 文件,g++ 编译 .cpp 文件。

C++ 文件后缀有很多种方法:.cpp,.cc,.cxx,互相之间没有区别。

  • 编译器起源:编译器是怎么被“编译”的?

    • 早期:人们用二进制写软件

    • 中期:人们用汇编写软件,但是计算机不认识汇编,所以需要一个编译器,把汇编语言转换成编译器。此时的编译器不能直接用汇编语言写,只能用二进制写软件

    • 后期:人们用高级语言写代码,计算机也不认识高级语言,此时有了汇编这个“桥梁”,所以只需要把高级语言转换成汇编语言。自然的,编译器也不能直接用高级语言写,得用汇编写

      同时,由于二进制原始编译器可以把汇编语言转换成二进制文件,那么我们可以用汇编语言重写汇编的编译器,这样重写的编译器就可以用原始编译器编译并被机器识别。

      因此,有了汇编原始编译器,我们就可以使用高级语言重写高级语言编译器,然后交给汇编原始编译器进行编译。

      这个过程叫做语言/编译器"自举"的过程。

  • 编译器全过程:

    • 预处理:头文件展开,去注释,条件编译,宏替换

      条件编译的好处:可以动态裁剪代码,形成同一个软件的不同版本.

    • 编译:C 语言 -> 汇编

    • 汇编:汇编 -> 可重定位二进制文件

    • 链接:形成可执行文件

  • gcc 选项:

    • -E 只进行预处理,后面的工作不进行,一般文件的后缀是 .i

    • -o <文件名> 把结果输出到对应文件中

    • -S 进行到编译结束,后面的工作不进行,一般文件的后缀是 .s

    • -c 进行到汇编结束,后面的工作不进行,一般文件的后缀是 .o

    • -static 以静态链接的方式编译代码

      od <文件名> 可以打开二进制文件。

  • 链接 - 动静态库:

    ldd <文件名> 查看文件所依赖的第三方库。

    • 我们的代码 + 头文件 + 库 = 我们的可执行程序

    • 开发环境安装:安装,下载并拷贝头文件和库文件到开发环境的特定路径下,能够被编译器找到

      库的命名:

      • 以 lib 开头

      • 中间部分表明是动态库还是静态库

        • 在 Linux 系统下,.so 结尾的叫动态库,.a 结尾的叫做静态库

        • 在 Windows 系统下,.dll 结尾的叫动态库。.lib 结尾的叫做静态库

        一般系统里的动态库居多。

      • 最后的后缀是版本号

      • 去掉上述的三个部分,剩下的名字就是库的真正名称

    • 动态库:是 C / C++ 或者其他第三方提供的所有方法的集合,被所有的程序以链接的方式关联起来,动态链接

      库中所有的函数,都有入口地址。所谓的动态链接,其实就是把要连接的库中的函数地址拷贝到我们的可执行程序的特定位置。

      • 优点:形成的可执行程序体积比较小,比较节省资源(磁盘和内存空间,加载时间)

      • 缺点:稍慢一些,强依赖动态库,所有的依赖这个库的程序都无法运行了

    • 静态库:是 C / C++ 或者其他第三方提供的所有方法的集合,被所有程序以拷贝的方式,将需要的代码,拷贝到自己的程序中,静态链接

      • 优点:无视库,可以独立运行

      • 缺点:体积太大,浪费资源

      编译器默认编译的方式是动态链接。

      开发环境必须要做的三件事:

      • 下载开发环境 include,lib

      • 设置合理的查找路径

      • 规定好我们形成可执行程序的链接方式

      以后库找不到就可以从这三方面找问题

4. make / makefile

makefile 是一种自动化构建代码的工具。

  • make:是一个命令

    • Makefile 文件的第一个目标文件是默认的,只写 make 就会默认执行这个目标的依赖方法

    • make 目标文件名 执行对应文件的依赖方法

    • make 可以自动检测文件是否被更新,如果没有被更新,那么不能重复编译,提高了编译效率

      原理:如果源文件的修改时间(Mtime) > 可执行文件的修改时间(Mtime),说明源文件被修改了

      touch 直接更新文件的时间,就能重新编译这个文件。

  • 文件的三种时间:

    • Access time:该文件的最近访问时间(对文件的内容进行读取)

      一般而言,一个文件被查看的频率非常高,而文件存储在磁盘中,如果每次查看都要更改 Atime,那么 Linux 系统会充满对硬盘的 I/O 操作,降低系统效率。因此,系统设定只有间隔了一段时间之后或者多次更改之后才会更改 Atime。

    • Modify time:对文件内容的最后一次修改时间

    • Change time:对文件属性的最后一次修改时间

    三种时间之间存在联动关系:

    • Ctime 可能只是自己更改,不改变其他时间(例如,更改文件的权限)

    • Mtime 改变可能会影响 Ctime 和 Atime 改变

  • makefile:是一个在当前目录下存在的一个具有特定格式的文本文件

    • 第一行:依赖关系,写法:<想要生成的文件名> : <源文件名>

    • 第二行:依赖方法,写法:<tab>生成该文件的方式,例如 <tab>gcc code.c -o mybin

      <tab> 不能用四个空格代替。

      现实中,依赖关系和依赖方法相组合,就能描述清楚一件事情的原因和做法,就能达到我们的目标。

    • 清理对应的可执行文件,包括对应的临时文件:

      • 第一行:.PHONY:<伪目标文件名> 生成一个伪目标文件

        .PHONY 修饰的目标文件总是被执行。例如,正常的目标文件不能被重复编译,但是用其修饰的可以。

        此时 make 不再对比 Mtime。

      • 第二行:<伪目标文件名>:

        伪目标文件不需要依赖关系。

      • 第三行:依赖方法。例如:rm -f mybin

        依赖方法可以不止一个,通过回车来分隔。

    动态库是二进制文件。

  • make,Makefile 是有自动推导能力的

  • 小技巧:

    • 在默认情况下,make 会把依赖方法打印到屏幕上。如果不需要回显命令,就要在依赖方法前面加上 @

    • # 可以注释掉 Makefile 的一行

    • 在 Makefile 中,可以在代码开始处编写变量。例如:cc=gcc src=code.c target=mybin

      不建议带有空格。

      使用 $(<变量名>) 来进行变量替换

    • 可以使用 $^ 表示依赖关系中的源文件(冒号右侧),用 $@ 表示依赖关系中的目标文件(冒号左侧)

5. Linux 第一个小程序:进度条

  • 三个版本:

    1. 简单原理版本

    2. 实际工程实践版本

    3. C 语言扩展 - 带上颜色

  • 缓冲区:输出缓冲区存在于 FILE *stdout 中,调用 fflush 可以强制刷新它。用 \n 也是一种刷新方式(行刷新)。

  • 回车,换行:

    • 回车:使光标回到屏幕最左侧,用 \r 表示

    • 换行:使光标挪动到下一行。但实际上,\n 代表回车 + 换行

    向显示器打印的数字,真的是数字吗?

    实际上,向显示器打印 10,显示器输出的是 '1' 和 '0' 字符。是 printf 函数的 %d 帮助我们完成了格式转换,所以这个函数叫做格式化控制函数,显示器也叫做字符设备。

    同理,从键盘输入的 10,也不是数字,是由于 scanf 帮助完成了格式化输入。

6. git

  • 什么是 git:

    • git 是一个版本控制器

    • git 是一个软件,既是客户端,又是服务器

    • git 只会记录变化

    • git 是分布式软件,去中心化

  • GitHub / Gitee:网站,基于 git 软件搭建的网站 - 让版本管理可视化

  • git 命令:详见 C 语言仓库

7. GDB

GDB 是用来调试代码的工具。

gcc 默认编译的选项是 release,不能被调试(没有 debug 信息)。

  • gcc -g 让代码以 debug 方式发布,是代码可被调试的前提

  • gdb <目标文件名> 调试目标文件,进入 GDB 窗口

    在 GDB 窗口下的命令:

    • quit 退出 gdb

    • l[ist] [number] (从对应行号开始) 打印代码,之后一直回车就可以连续打印后边的代码

      list 有记忆功能,会接着上一次 list 的末尾代码开始打印。

    • r[un] 使代码直接进行调试,如果不打断点就运行完毕

    • b [源文件名:]<number> 在文件的 num 行打一个断点

    • b [源文件名:]<函数名> 在文件的该函数第一行打断点

    • info b 查看断点

    • d <断点编号> 删除对应断点

    • n[ext] 逐过程,不进入函数

    • s[tep] 逐语句,进入函数

    • until <行号> 运行至指定位置

    • finish 跳出,运行至函数结束

    • c[ontinue] 从一个断点直接运行到下一个断点处

    • p <变量名> 监视变量

    • display <变量名> 常显示变量

    • undisplay <条目编号> 取消常显示

    • set var <变量名> = <值>

    • bt 查看调用堆栈

      • gdb 中的断点编号是线性增长的,即使删除了断点,断点编号也不会回退。

      • 如果退出 gdb,那么所有断点都会被删除。

    • disable/enable <断点编号> 关闭/开启断点

    Linux 系统中形成的可执行程序格式,叫做 ELF 格式。

  • readelf -a <目标文件名> 查看可执行文件详情

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值