yum(Yellow dog Updater,Modified)是一个在 Fedora,RedHat 以及 SUSE 中的 Shell 前端软件包管理器。基于 RPM 包管理,能够从指定的服务器自动下载 RPM 包并且按照,可以自动处理依赖性关系,无需繁琐的下载、安装。yum 提供了查找、安装、删除某一个、一组甚至全部软件包的命令。
进行 yum 的所有操作必须联网,因为 yum 需要从服务器上下载 PRM 包。可以通过 ping 指令判断当前服务器是否联网。以下为联网状态:
通过 yum list 命令可以查看当前一共有哪些软件包,
[hy@VM-16-4-centos linux4]$ yum list
Linux 系统下的软件包数目非常多,我们可以使用 grep 命令来筛选出我们所关注的包。例如:
注意:
安装软件指令:sudo yum install 软件名
.
yum会自动找到有哪些软件包需要下载,这时我们需要输入 “y” 进行确认安装。当出现 “complete” 字样时,说明安装完成。
例如:
❗注意:
卸载软件指令:sudo yum remove 软件名
.
yum会自动卸载该软件,卸载过程中需要确认是否卸载,输入 ‘y’ 表示确认卸载,出现 “complete!” 时表示卸载完成。
在使用 rz/sz 之前,我们需要先安装 lrzsz,使用此命令进行安装sudo yum install lrzsz
。安装完成之后通过拖拽的方式将文件上传过去。
如下:可以通过直接拖拽文件的方式上传文件到 Linux 所在的当前目录下。
可以通过指令 rz -E
来选择需要从本地机器上传到云服务器的文件:
指令:sz 文件名
该指令可将 Linux 云服务器上的文件下载到 Windows 机器的指定文件夹中。
vim 是 vi 发展出来的一个文本编辑器。代码补全、编译及错误跳转等方便编程的功能特别丰富,本质上是一个多模式的文本编辑器。
基本上 vi/vim 共分为三种模式:命令模式(Command mode),插入模式(Insert mode),底行模式(Last line mode)。这三种模式的作用分别是:
首先我们打开 vim ,vim 文件名
,进入 vim 后默认为命令模式,需要切换模式按照以下执行:
如上图所示:
命令模式 ➡️ 插入模式: 输入 a/i/o 中的任意一个字符进入插入模式。
插入模式 ➡️ 命令模式: 直接按下 “Esc” 键。
命令模式 ➡️ 底行模式: 输入 “shift + :” ,实际上就是输入 “:” 。
退出 vim 及保存文件: 命令模式下,“shift + :” 进入底行模式,w(保存当前文件),wq(存盘并退出 vim),q!(不存盘强制退出 vim)。
vim 命令模式命令集:
🌏移动光标
🌏删除文字
🌏复制粘贴
🌏替换
🌏撤销上一次操作
🌏更改
🌏跳至指定的行
在使用底行模式之前,先将 vim 调至命令模式,再按 “shift + :” 即可进入底行模式。
🌏设置行号
🌏跳到文件中的某一行
🌏查找字符
🌏分屏指令
🌏执行指令
需要熟悉掌握 vim ,这里推荐一个参考资料:vim from zero to hero(vim 从入门到牛逼)
1.-E 完成程序预处理,不生成文件,你需要将它重定向到一个输出文件中
2.-S 编译到汇编语言就不进行汇编和链接
3.-c 编译到目标文件
4.-o 文件输出到文件
5.-static 对生成的文件采用静态链接
6.-g 生成调试信息。GNU 调试器可利用该信息
7.-shared 此选项尽量使用动态库,所以生成的文件比较小,但是需要系统中安装由动态库
8.-O3 编译器的优化选项的4个级别,-O0 表示没有优化,-O1 为缺省值,-O3 优化级别最高
9.-w 不生成任何警告信息
10.-Wall 生成所有警告信息
接下来用 gcc/g++ 来演示一下程序生成的四个阶段:预处理、编译、汇编、链接。
预处理
[hy@VM-16-4-centos linux2]$ gcc -E test.c -o test.i
编译
[hy@VM-16-4-centos linux2]$ gcc -S test.i -o test.s
汇编
[hy@VM-16-4-centos linux2]$ gcc -c test.s -o test.o
链接
[hy@VM-16-4-centos linux2]$ gcc test.o -o test
在我们的程序中,其中使用的库函数,例如:cout,并没有在我们的程序中实现,且在预编译中包含的 “stdio.h” 中也只有该函数的声明,而没有定义函数的实现,那么函数是在哪里实现的呢?系统把这些函数实现都放到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径 “/usr/lib” 下进行查找,也就是链接到 libc.so.6 的库函数中去,因此我们代码中并没有实现 cout,但是也可以使用,这就是链接的作用。
函数库一般分为动态库和静态库:
动态库与静态库的优缺点:
动态库
优点:节省磁盘空间,更加节省内存并减少页面交换,适用于大规模的软件开发,使开发过程独立,耦合度低。加载速度快等。
缺点:发布程序需要提供依赖的动态库,速度比静态链接慢。
静态库
优点:静态库被打包到程序中加载速度快、发布程序无需提供静态库,移植方便。
缺点:相同的库文件数据可能在内存中被加载多份,消耗系统资源,浪费内存。库文件更新需要重新编译项目文件,生成新的可执行程序,浪费时间。
使用 ldd 指令查看当前程序的链接状态以及所依赖的库:
gcc/g++ 默认生成的二进制程序是动态链接的,可以通过 file 指令来查看:
gcc/g++ 编译程序默认采用的是动态链接,若需要使用静态链接,则加上 -static 选项即可。
[hy@VM-16-4-centos linux2]$ gcc test.c -o testA -static
❗若加上 -static 选项后没有执行成功,那么可能是没有安装静态库。安装静态库的命令如下:
[hy@VM-16-4-centos linux2]$ sudo yum install -y glibc-static
[hy@VM-16-4-centos linux2]$ sudo yum install -y libstdc++-static
GNU symbolic debugger,简称「GDB 调试器」,是 Linux 平台下最常用的一款程序调试器。GDB 编译器通常以 gdb 命令的形式在终端(Shell)中使用。发展至今,GDB 调试器已经对 C、C++、Go、Objective-C、OpenCL、Ada 等多种编程语言提供了支持。实际场景中,GDB 更常用来调试 C 和 C++ 程序,虽然 Linux 平台下有很多能编写 C、C++ 代码的集成开发工具(IDE),但它们调试代码的能力往往都源自 GDB 调试器。
程序发布的方式有两种:debug模式 和 release模式。 debug模式包含程序的调试信息,在次模式下可以对程序进行调试;release模式不包含程序的调试信息,该模式下的程序不能被调试。
在 Linux 下,gcc/g++ 默认生成的程序是 release 版本的,不包含调试信息。若程序需要使用 gdb 调试,需要在 gcc/g++ 生成可执行程序时加上 -g 选项:
包含调试信息的可执行程序,使用 gdb 进行调试,首先需要进入 gdb :gdb 文件名
.
run/r
:运行程序。
n/next
:逐过程进行调试,单条执行。
s/step
:逐语句进行调试,进入函数调用。
b/break 行号
:在某一行设置断点。
break 函数名
:在某个函数开头设置断点。
info break
:查看断点信息。
finish
:执行到当前函数返回,然后停下来。
p 变量
:打印变量值。
list/l 行号
:显示程序源代码,接着上次的位置往下列,每次列10行。
list/l 函数名
:列出某个函数的源代码。
print(p)
:打印表达式的值,通过吧表达式可以修改变量的值或者调用函数。
set var
:修改变量的值。
c/continue
:从当前位置开始连续而非单步执行程序。
delete breakpoints
:删除所有断点。
delete breakpoints n
:删除序号为 n 的断点。
disable breakpoints
:禁用断点。
enable breakpoints
:启用断点。
display 变量名
:跟踪查看一个变量,每次停下来都显示它的值。
undisplay
:取消对先前设置变量的跟踪。
until n行号
:跳转至 n 行。
breaktrace/bt
:查看各级函数调用及参数。
info (i)locals
:查看当前栈帧局部变量的值。
quit
:退出 gdb。
make 是一个命令工具,它解释 Makefile 中的指令。在 Makefile 文件中描述了整个工程所有文件的编译顺序、编译规则。Makefile 有自己的书写格式、关键字、函数。像 c语言 有自己的格式、关键字和函数一样。而且在 Makefile 中可以使用系统 shell 所提供的任何命令来完成想要的工作。
make/makefile 的重要性
make 是依赖于 makefile 的,要运行 make ,当前目录下就必须要有名为 makefile 的文件。makefile 是阐述依赖关系和依赖方法的。makefile 文件命名只能是 makefile/Makefile 两种命令方法。依赖关系与依赖方法相互搭配,依赖方法必须以 Tab 键开头。
Makefile 文件中,需要写的是依赖关系和依赖方法,例如生成的可执行程序 test 依赖的就是 test.c 文件,test 程序是由 test.c 源文件经过处理生成的,而生成可执行程序的过程依赖方法 gcc test.c -o test ,即用 gcc/g++ 来编译链接生成可执行程序。
在一般的工程项目中,有着许多的源文件,面对着众多的源文件,我们应该怎样来编译这些文件生成可执行程序呢?以下演示一个最简单的:
在面对多个文件时,若我们使用上述方法进行文件的编译,可能给我们带来的问题:
针对多文件的项目,就需要使用 make/makefile 了,这将降低编译文件的出错率,提高工作效率。
step1:在源文件所在的目录下面创建一个名为 makefile/Makefile 的文件。
step2:编写 makefile/Makefile 文件并保存。依赖方法必须以 Tab键 开头。
step3:编写好 makefile 后,若需要生成可执行程序,直接在命令行中输入 “make” 即可。
工程是需要被清理的。在每次需要重新生成可执行程序时,都需要对上一次生成的可执行程序进行清理,每次清理都在命令行中使用命令清理会很麻烦。因此,我们可以将清理生成的可执行程序的方法写入 makefile 中,便于对生成的程序进行清理。
.PHONY:用该关键字修饰的是一个伪目标,该目标总是被执行的。上图中,生成可执行程序的依赖关系和依赖方法没有被 .PHONY 修饰,因此 make 命令执行生成了可执行程序之后,若源文件没有被修改过的话,再次执行 make 命令是不会执行成功的。而需要被清理的可执行程序用 .PHONY 修饰了,所以每次执行 make clean 时,都是执行写入的依赖方法。
❓那么问题来了,makefile 是如何识别 exe/bin 是新的还是旧的,源文件有没有被更改过呢?
使用 stat 命令可以查看程序或文件的三个时间,Modify 表示文件最近一次被修改的时间,Access 表示最近一次访问该文件的时间,Change 表示文件属性更改的最近时间。
可执行程序是由源文件生成的,所以源文件的 Modify 时间要早于可执行程序的 Modify 时间,因此,gcc/g++ 只需要对比源文件与可执行程序的最近修改时间(Modify),便可知道程序是否需要重新生成。若可执行程序的 Modify 时间早于源文件的 Modify 时间,说明源文件被修改过,则需要编译程序生成新的可执行程序,否则不需要重新进行编译。
注意:若可执行程序是最新的,不能再次生成新的可执行程序。若需要再次生成新的可执行程序,可以使用 touch 文件名
更新文件/程序的三个时间为当前执行命令的最新时间。
touch test.c // 将该文件的三个时间更新为当前的最新时间
上一篇:哈希的应用 —— 布隆过滤器
下一篇:React组件