目录
一、软件包管理器——yum
1.Linux下安装程序的方式
在Linux环境下安装软件的方式有以下几个方式:
1)源码安装,直接下载源代码,让它自行编译运行形成可执行程序。
2)软件包安装,下载rpm安装包,通过rpm包获取资源安装。
3)包管理器安装,通过yum安装(推荐),ubuntu(apt)这个方式类似于我们手机上的应用商店。(这个方式可以解决包的依赖问题)
2.什么是yum
定义:
YUM(Yellowdog Updater, Modified) 是基于 RPM(Red Hat Package Manager)的软件包管理工具,主要用于 Red Hat 系列 Linux 系统(如 RHEL、CentOS、Fedora 等),用于自动化安装、更新、卸载软件包,以及管理软件包之间的依赖关系,一次性解决安装的问题。
敲黑板:一个云服务器在同一时间只允许一个yum进行安装,不能在同一时刻安装多个软件。
温馨提示:在通过yum进行安装时,我们首先要保证服务器或虚拟机是处在联网状态的,可以通过下面这个命令来验证是否联网,如果没有打印任何信息则没有连上网,需要检查网络配置。
3.查找软件包
我们可以通过以下命令来查看可以下载的软件:
yum list
注意事项:
1)软件包名称:主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构。
2)"x86_64"后缀表示64位系统的安装包,"i686"后缀表示32位系统安装包,选择包时要和系统匹配。
3)"el7"表示操作系统发行版的版本,“el7"表示的是"centos7/redhat7”,“el6"表示"centos6/redhat6”。
4)最后一列表示的是“软件源”的名称,类似于“小米应用商店”,“华为应用商店”这样的概念。
这里拿lrzsz做一个说明:
先解释一下这个软件包是什么:lrzsz可以将Windows当中的文件上传到Linux当中,也可以将Linux当中的文件下载到Windows当中,实现云服务器和本地机器之间进行信息互传。
yum list | grep lrzsz
4.安装软件
指令:sudo yum install 软件名
例如:我们要安装的lrzsz
# Centos
$ sudo yum install -y lrzsz
# Ubuntu
$ sudo apt install -y lrzsz
敲黑板:
1)由于安装软件是在系统目录下,所以我们需要使用sudo或者直接是用root账户去安装
2)yum安装软件只能装完这一个再去装下一个,不然会报错的。
5.本地与服务器端进行文件互传
我们安装好了lrzsz,那么我们就可以进行本地和服务器之间进行互传。
指令:rz
通过这个命令可以实现本地向服务器传文件。
指令:sz
通过这个指令可以实现从服务向本地导文件。
6.卸载软件
指令:sudo yum remove 软件名
# Centos
sudo yum remove [-y] lrzsz
# Ubuntu
sudo apt remove [-y] lrzsz
通过这个命令可以卸载软件,中途需要按下"y"来确认。
二、Linux的编辑器——vim
1.基本概念
我们这里介绍最常用的几种模式,分别是命令模式、插⼊模式和底⾏模式,各模式的功能区分如下:
1)正常/普通/命令模式(Normal mode)
控制屏幕光标的移动,字符、字或⾏的删除,移动复制某区段及进⼊Insert mode下,或者到 last line mode
2)插入模式(Insert mode)
只有在Insert mode下,才可以做⽂字输⼊,按「ESC」键可回到命令⾏模式。该模式是我们后面用的最频繁的编辑模式。
3)末行模式(Last line mode)
⽂件保存或退出,也可以进⾏⽂件替换,找字符串,列出行号等操作。 在命令模式下,*shift+:*即可进⼊该模式。要查看你的所有模式:打开vim,底⾏模式直接输⼊ :help vim-modes
2.vim下各个模式之间的切换
指令:vim 文件名
vim test.c
我们在进入vim后,默认是在命令行模式,需要敲击(i/a/o)进入插入模式。
【命令模式】切换至【插入模式】
1)输入「i」:在当前光标处进入插入模式。
2)输入「a」:在当前光标的后一位置进入插入模式。
3)输入「o」:在当前光标处新起一行进入插入模式。
【命令模式】切换至【底行模式】
1)输入[Shift+;」 即可,实际上就是输入「:」
【插入模式】或【底行模式】切换至【命令模式)
1)插入模式或是底行模式切换至命令模式都是直接按一下「Esc」键即可。
3.vim在命令行模式下的命令汇总
移动光标:
vim可以直接用键盘上的光标来上下左右移动,但正规的vim是用小写英文字母「h」、「j」「k」、「I」,分别控制光标左、下、上、右移一格
1)按「G」:移动到文章的最后
2)按「$」:移动到光标所在行的“行尾
3)按「^」:移动到光标所在行的“行首
4)按「w」:光标跳到下个字的开头
5)按「e」:光标跳到下个字的字尾
6)按「b」:光标回到上个字的开头
7)按「#」:光标移到该行的第#个位置,如:5l,56l
8)按[gg]:进入到文本开始
9)按[shift+g]:进入文本末端
10)按「ctrl」+「b」:屏幕往“后”移动一页
11)按「ctrl」+「f」:屏幕往“前”移动一页
12)按「ctrl」+「u」:屏幕往“后”移动半页
13)按「ctrl」+「d」:屏幕往“前”移动半页
删除文字:
1)「x」:每按一次,删除光标所在位置的一个字符
2)「#x」:例如,「6x」表示删除光标所在位置的“后面(包含自己在内)”6个字符
3)「X」:大写的X,每按一次,删除光标所在位置的“前面”一个字符
4)「#X」:例如,「20X」表示删除光标所在位置的“前面”20个字符
5)「dd」:删除光标所在行
6)「#dd」:从光标所在行开始删除#行
复制:
1)「yW」:将光标所在之处到字尾的字符复制到缓冲区中。
2)「#yW」:复制#个字到缓冲区
3)「yy」:复制光标所在行到缓冲区。
4)「#yy」: 例如,「6yy」表示拷贝从光标所在的该行“往下数”6行文字。
6)「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能。
替换:
1)「r」:替换光标所在处的字符。
2)「R」:替换光标所到之处的字符,直到按下「ESC」键为止。
撤销上一次操作:
1)「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回复。
2)「ctrl+r」:撤销的恢复
更改:
1)「cw」:更改光标所在处的字到字尾处
2)「c#w」:例如,「c3w」表示更改3个字
跳至指定行:
1)「ctrl」+「g」列出光标所在行的行号。
2)「#G」:例如,「15G」,表示移动光标至文章的第15行行首。
4.vim在底行模式下的命令汇总
这里跳至底行的方法是,一直Esc(避免你不知道是在哪一个模式下),再按【:】进入底行模式。
行号设置:
1)「set nu」:输入后,会在文件中的每一行前面列出行号。
2)「set nonu」:取消行号。
跳至某一行:
「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字
15,再回车,就会跳到文章的第15行。
查找字符:
1)「/关键字」:先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止。
2)「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可
以一直按「n」会往前寻找到您要的关键字为止。
保存文件:
[w」:在冒号输入字母「w」就可以将文件保存起来
离开vim:
1)「q」:按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim。
2)「wq」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。
5.关于vim的配置
vim的配置是一人一份的,一个用户配置的是自己的并不影响别人。每个人虽然用的是同一个vim程序,但是大家用的是vim不同的配置(每个用户在自己的家目录下都有属于自己的配置文件)
我们需要创建.vimrc文件,并在自己的.vimrc文件中添加一系列的命令,充当于vim的配置文件。所谓的vim的基本配置,就是修改自己的vimrc!
如果是自己配置的话比较麻烦,所以这里提供一个码云上面的自动一键配置vim的命令。
curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh
配置完成之后:
但是要注意的是,这个的默认缩进是两个空格,我们可以打开.vimrc来配置。
三、Linux中的编译器——gcc和g++
1.gcc和g++的作用
gcc和g++分别是c和c++的编译器,它们在执行编译时,有如下几个步骤:
1)预处理(进行宏替换/去注释/条件编译/头文件展开等)
2)编译(生成汇编)
3)汇编(生成机器可识别代码)
4)连接(生成可执行文件或库文件)
2.gcc和g++的语法
格式:gcc/g++ 选项 文件
选项 | 功能描述 |
---|---|
-c | 仅编译不链接,生成目标文件 (.o) |
-S | 生成汇编代码文件 (.s) |
-E | 仅进行预处理,不编译 |
-o <file> | 指定输出文件名为<file> |
-g | 生成调试信息,用于 GDB 调试 |
-O0 | 不进行优化(默认) |
-O1 | 基本优化 |
-O2 | 更高级优化(推荐) |
-O3 | 最高级优化(可能增加编译时间) |
-Os | 优化代码大小 |
3.预处理
作用:头文件展开,去注释,宏替换,条件编译
指令:
gcc -E hello.c -o hello.i
说明:
选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o””是指目标文件,“.i”文件为已经过预处理的C原始程序。
4.编译
作用:
在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。
指令:
gcc -S hello.i -o hello.s
说明:
用户可以使用-S选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
-o选项是指目标文件,“xxx.s”文件为已经过翻译的原始程序。
5.汇编
作用:将汇编代码转变为二进制码。
指令:
gcc -c hello.s -o hello.o
说明:
汇编阶段是把编译阶段生成的“xxx.s”文件转成目标文件。
使用-c选项就可以得到汇编代码转化为“xxx.o”的二进制目标代码了。
6.链接
作用:链接就是将生成的各个“xxx.o”文件进行链接,生成可执行文件。
指令:
gcc hello.o -o hello
说明:
gcc/g++不带-E、-S、-c选项时,就默认生成预处理、编译、汇编、链接全过程后的文件。
若不用-o选项指定生成文件的文件名,则默认生成的可执行文件名为a.out。
敲黑板:链接产生的文件也是二进制的。
7.动静态库
函数库可以分成动态库和静态库:
1)静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
2)动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由
运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”
有动静态库,那么就有了动静态链接:
动态链接:
优点:节省空间,易于更新,灵活性高。
缺点:依赖外部环境,加载时间长,不同程序可能依赖同一库的不同版本,可能会引发版本冲突问题。
静态链接:
优点:独立性强,加载速度快,便于我们调试。
缺点:占用空间大,更新维护困难,资源浪费。
我们是用gcc和g++链接时默认是动态链接的,可以通过file指令查看:
我们还可以通过ldd来查看所依赖的库。
敲黑板:
Linux下,动态库XXX.so,静态库XXX.a
Windows下,动态库XXX.dll,静态库XXX.lib
那么我们如何实现静态链接呢?
这里我们在编译时只需要带上-static的选项即可。
我们还可以查看一下两种链接方式的文件大小的区别:
很明显,静态链接方式的文件更大,说明了动态链接节省空间。
四、Linux中的调试器——gdb
1.背景知识
程序的发布模式有两种,分别是debug模式和release模式,而调试只能在debug模式下。
Linux 的gcc和g++编译出来的二进制程序,默认是release模式,所以默认是不支持调试的。
如果是想实现调试则需要在生成二进制程序时,加上-g选项。
我们也可以对比一下在relesase和debug模式下两个可执行程序的大小。
我们发现在debug模式下还是要比release模式下的可执行程序的大一些。
2.gdb命令的汇总
基本上都是用过即可。
进出gdb:
进入:gdb 二进制文件
退出:ctrl+d或quit 调试命令
调试:
1)run/r:运行代码(启动调试)
2)next/n:逐过程调试。
3)step/s:逐语句调试。
4)until 行号:跳转至指定行。
5)finish:执行完当前正在调用的函数后停下来(不能是主函数)
6)continue/c:运行到下一个断点处。
7)set var 变量=x:修改变量的值为x。
显示:
1)list/l n:显示从第n行开始的源代码,每次显示10行,若n未给出则默认从上次的位置往下显示。
2)list 函数名:显示该函数的源代码。
3)print/p 变量:打印变量的值。
4)print/p &变量:打印变量的地址。
5)print/p 表达式:打印表达式的值,通过表达式可以修改变量的值。
6)display 变量:将变量加入常显示(每次停下来都显示它的值)。
7)display &变量:将变量的地址加入常显示。
8)undisplay 编号:取消指定编号变量的常显示。
9)bt:查看各级函数调用及参数。
10)info/i locals:查看当前栈帧当中局部变量的值。
断点:
1)break/b n:在第n行设置断点。
2)break/b 函数名:不在某函数体内第一行设置断点。
3)info breakpoint/b:查看已打断点信息。
4)delete/d 编号:删除指定编号的断点。
5)disable 编号:禁用指定编号的断点。
6)enable 编号:启用指定编号的断点。
五、Linux——自动化构建工具
1.背景知识
1)会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
2)一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作
3)makefile带来的好处就是--“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
4)make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,VisualC++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。
5)make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。
2.依赖关系和依赖方法
我们在写makefile一定要首先理解各个文件之间的依赖的关系以及它们之间的依赖方法。
依赖关系:文件A的变化会影响到文件B,那么我们就称文件B依赖于文件A。
比如:文件hello.o是由文件hello.c文件通过预处理、编译以及汇编产生的,所以hello.c的改变会影响到hello.o,也就是hello.o依赖hello.c。
依赖方法:如果文件B依赖于文件A,那么通过文件A得到文件B的方法,就是文件B依赖于文件A的依赖方法。
比如:hello.o依赖于hello.c,而hello.c通过gcc -c hello.c -o test.o指令就可以得到test.o,那么hello.o依赖于hello.c的依赖方法就是gcc -c hello.c -o test.o。
3.多文件编译
如果我们有很多个源文件需要编译,应该怎么办呢?
这里我们可以使用常用的方法,直接使用gcc。
我们讲行多文件编译的时候一般不使源文件直接生成可执行程序,而是先用每个源文件各自生成自己的二讲制文件,然后重将这些一进制文件通过链接生成可执行程序。
那么我们为什么要这么做呢?
因为如果我们修改了其中的一个源文件,那么我们再生成可执行是就需要重新再把所有的源文件进行编译链接。而如果是把各个源文件生成各个二进制文件,那么修改后只需要把修改的文件重新编译生成二进制文件,然后在把二进制文件链接。
但是随着源文件的数量增加,我们如果还是以之前的方式就会极其的恶心,这个时候我们就需要用到make和makefile来大大减少工作量。
4.如何编写makefile
第一步:在源文件所在目录下创建了一个makefile/Makefile文件
第二步:编写makefile文件
保存并退出后,make执行后便可以得到我们想要的文件。
makefile中的技巧写法:
符号 | 含义 |
---|---|
$@ | 当前规则的目标文件名。 |
$< | 第一个依赖文件的名称。 |
$^ | 所有依赖文件的列表,以空格分隔(去重)。 |
上面代码的简写:
make的工作原理:
1)make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2)如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到 myproc 这个文件,并把这个文件作为最终的目标文件。
3)如果 myproc 文件不存在,或是 myproc 所依赖的后面的 myproc.o 文件的文件修改时间要比 myproc 这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成myproc 这个文件。
4)如果 myproc 所依赖的 myproc.o 文件不存在,那么 make 会在当前文件中找目标为myproc.o 文件的依赖性,如果找到则再根据那一个规则生成 myproc.o文件。(这有点像一个堆栈的过程)
5)当然,你的C文件和H文件是存在的啦,于是make会生成 myproc.o 文件,然后再用myproc.o 文件声明 make 的终极任务,也就是执行文件 hello 了。
6)这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
7)在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
8)make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
5.项目清理
在执行完后,有可能我们需要删除之前的执行的结果文件再执行新的文件,那么我们应该如何实现和执行相似的过程呢?
这样写好之后我们只要make clean就可执行之前写的代码。
敲黑板:
一般将这种clean的目标文件设置为伪目标,用.PHONY修饰,伪目标的特性是:总是被执行。