目录
1. Linux软件包管理器
1.1 如何在Linux安装软件?
-
源码安装
-
rpm(Linux安装包)安装
但是软件之间存在大量的依赖关系,安装比较麻烦
-
yum :Linux下进行软件安装的一种客户端,可以自动处理依赖性关系,并且一次安装所有依赖的软件包,无须繁琐地一次次下载、安装。
-
[ yum list ] : 显示所有的程序
-
[ yum list | grep sl.x86_64 ] : 通过grep指令来过滤软件,只看sl.x86_64的程序。注意:
.
为特殊符号需要\
转义。
注意:
-
软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构。
-
“x86_64” 后缀表示64位系统的安装包, “i686” 后缀表示32位系统安装包. 选择包时要和系统匹配.
-
“el7” 表示操作系统发行版的版本. “el7” 表示的是 centos7/redhat7. “el6” 表示centos6/redhat6.
-
最后一列, base 表示的是 “软件源” 的名称, 类似于 “小米应用商店”, “华为应用商店” 这样的概念
-
[ yum (-y) install 程序名]:安装指定的软件。一般需要root权限,或sudo。
-y
选项,对所有的提问都回答yes。安装完成后输入 [ sl ] 指令
-
[ yum remove 程序名 ] :卸载软件。也是需要root权限或sudo
注意:
- yum要工作必须联网
- centos里面,只有一个yum在运行
-
1.2 关于rzsz
这个工具用于 windows 机器和远端的 Linux 机器通过 XShell 传输文件。
安装完毕之后可以通过拖拽的方式将文件上传过去。
-
安装
[ yum install lrzsz.x86-64 ]
-
[rz] 指令可选择文件夹中的文件加入。也可以直接拖拽入当前的路径目录中。
-
[sz 文件名] 指令可以发出文件。
2.Linux 文本编辑器——vim
vi/vim是一种多模式编辑器,vim是vi的升级版本。
2.1 vim的模式
vim一共具有12种模式:six BASIC modes 和 six ADDTIONAL modes 。
作为初学者首先掌握其中的三种模式:命令模式(command mode)、插入模式(insert mode)和底行模式(last line mode)。
- 命令模式/正常模式
控制光标的移动,字符,字或行的移动,复制或删除,不能在此模式下打字输入。打开vim即是此模式,在此模式下,可以进入插入模式和底行模式
- 插入模式
只有在此模式下才能执行文字输入。在插入模式下,敲击
Esc
键回退到命令模式。
- 底行模式
在 Vim 底部最后一行中输入命令,按回车并执行。可实现的功能如:文件的保存或退出,文件切换,查找字符串,显示行号等功能。在命令模式下,shift+:(即输入冒号),进入底行模式。在插入模式下,敲击
Esc
键回退到命令模式。
无论你现在在任何模式下,按 Esc 键可以让你回到命令模式!
2.2 vim的基本操作
-
vim test.c
如果存在test.c文件,vim直接打开此文件,否则将新建test.c文件。
进入vim时,默认打开为命令模式,需要切换插入模式才能编辑代码。
-
命令模式进入插入模式的方法如下
i
:在当前光标处进行编辑(insert)a
:在当前光标后进行编辑I
:在当前的行首开始编辑A
:在当前的行尾开始编辑o
:下方插入一行,从行首开始编辑O
:上方插入一行,从行首开始编辑
-
保存文件并退出vim
- 按esc进入命令模式
- shift+: 进入底行模式
q
退出(vim会提示未保存) ,w
保存 ,wq
保存并退出,q!
不保存强制退出。
2.3 命令模式下指令集
以下操作皆在命令模式下执行
基本移动
- [h] 光标向左移动一个字符
- [j] 光标向下移动一个单位
- [k] 光标向上移动一个单位
- [h] 光标向右移动一个单位
- [w] 向右移动一个单词
- [b] 向左移动一个单词
- [^] ==shift+6 光标位置锚点,快速定位到行首
- [$] ==shift+4 光标位置锚点,快速定位到行尾
- [gg] 定位到行首
- [G] ==shift+g 定位到行尾
- [ngg]/[nG] 移动到第n行。底行模式下输入[set nu]显示行号。
- [n%] 移动到文件的百分比处
- [n|] 移动到当前行的第n列
- [M] 移动到窗口的中间行
- [nH] 移动到距离窗口顶端第n行
- [nL] 移动到距离窗口底部第n行
文本操作
- [yy] 复制当前行
- [nyy] 复制当前以及其下共n行
- [p] 在当前行的下方粘贴
- [np] 复制n行
- [u] 撤销最近的改动
- [ctrl+r] 重做最近撤销的改动
- [dd] 删除当前行
- [dd]+[p] 实现剪切功能
- [ndd] 删除当前以及其下共n行
- [D] 删除到行尾
- [ x ] 删除光标后的字符
- [ nx ] 删除后续的n个字符
- [ X ] 删除光标前的字符
- [~] 切换大小写
- [r + 字符] 替换成字符
- [nr + 字符] 替换成n个字符
- [R] 进入替换模式(replace mode),接下去输入的内容会覆盖原有内容
2.4 底行模式命令
在插入模式下无法进入底行模式,需经由命令模式进入底行
- [set nu],[set number] 显示行号
- [set nonu] 取消显示行号
- [vs 文件名] 用vim打开另一文件并分屏,
- [ctrl+w+w] 使光标在不同文件中轮流切换(从左到右)
- [ctrl+w+h] 使光标左移直至最左侧
- [ctrl+w+l] 使光标右移直至最右侧
- [ctrl+w+r] 使光标当前文件右移
- [n] n为数字,光标跳转到n行
查找和替换
- [/关键字] 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往后寻找到您要的关键字为止
- [?关键字] 先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按「n」会往前寻找到您要的关键字为止
- [ 😒/p1/p2/g ] 将当前行中所有p1均用p2替代
- [ :n1,n2s/p1/p2/g ] 将第n1至n2行中所有p1均用p2替代
- [ :g/p1/s//p2/g ] 将文件中所有p1均用p2替换
2.5 vim的配置
vim配置在某一个用户中,那vim只会影响该用户的操作。
root也有自己的vim配置文件,且只会影响root自身。
配置文件的位置
在每个用户的主目录下面,都可以自己建立私有的配置文件,命名为.vimrc
。建立完成之后,打开文件,执行vim .vimrc
,然后在此文件中输入配置指令,那么该用户下vim进入的文件都已被配置。
常用的配置选项
- 设置语法高亮: [syntax on]
- 显示行号:[set nu]
- 设置缩进的空格数为4:[set shiftwidth=4]
更多vim配置可以参考:vim入门到精通
2.6 使用vim给用户添加sudo权限
linux下直接运行sudo命令,会提示类似:
xxxis not in the sudoers file. This incident will be reported.
这里,xxx是用户名称,然后导致无法执行sudo命令,这时候,如下解决:
-
进入超级用户模式。也就是输入
su
,系统会让你输入超级用户密码,输入密码后就进入了超级用户模式。(当然,你也可以直接用root操作) -
编辑/etc/sudoers文件。也就是输入命令
vim /etc/sudoers
进入插入模式,找到这一行:
root ALL=(ALL) ALL
然后在下面添加
xxx ALL=(ALL) ALL
(这里的xxx是你的用户名)最后保存退出就行了。
命令总览
3 Linux编译器——gcc/g++使用
3.1 代码生成可执行文件的步骤
- 预处理(宏替换,头文件展开,去注释,条件编译)
- 编译(生成汇编语言)
- 汇编(生成二进制代码供机器识别)
- 链接(生成可执行文件或库文件)
3.2 使用gcc
-
[ gcc 文件名.c ] 使用gcc编译器编译c文件,默认生成名为
a.out
的可执行文件(名字将一直是a.out)。由于只允许在C99模式下使用‘for’循环初始化声明,所以需要gcc指令中添加选项:
-std=c99
-
运行可执行文件
[ ./可执行文件 ] 运行可执行文件,如果是默认名
a.out
,则执行 [./a.out] 。也可以以绝对路径运行可执行文件:
[ 绝对路径/可执行文件 ]
gcc分别完成预处理、编译、汇编、链接
语法:[ gcc 选项 要处理的文件 选项 生成的文件 ]
预处理 ◔
-
预处理的功能:去注释,文件包含,宏替换,条件编译等
-
预处理指令是以`#``k开头的代码行
-
语法:[ gcc -E 文件名.c -o 文件名.i]
-
选项 -E:该选项的作用是让gcc在预处理完后停止编译过程🛑。
-
选项 -o:用于指定要生成的结果文件,后面跟的就是结果文件名字。o是output的意思,不是目标的意思。
-
如果没有-o选项(不生成结果文件),那预处理的结果会直接显示在屏幕上。
-
[vim 预处理文件] 可查看预处理文件内容
编译 ◑
-功能:在此阶段编译器检查代码语法的规范性,无误后把代码翻译成成汇编语言。
编译过程为扫描程序–>语法分析–>语义分析–>源代码优化–>代码生成器–>目标代码优化;
语法分析的结果为分析树parse tree或者语法树syntax tree
-语法:
-
[ gcc -S 文件名.c ] 编译.c文件,编译结束后停止🛑,默认自动生成与c文件同名的后缀为.s文件。
-
[ gcc -S 文件名.i ] 直接对已有的预处理文件编译,那就省略了预处理的步骤,自动生成与c文件同名的后缀为.s文件。
-
[ gcc -S 文件名.c -o 文件名.s ] 编译完成后,生成自己指定的文件
已翻译为汇编语言
汇编 ◕
-
功能:
汇编实际上指把汇编语言代码翻译成目标机器指令(二进制)的过程。对于被翻译系统处理的每一个C语言源程序,都将最终经过这一处理而得到相应的目标文件。
目标文件中所存放的也就是与源程序等效的目标的机器语言代码。目标文件由段组成。通常一个目标文件中至少有两个段:
- 代码段:该端中包含的主要是程序的指令。
- 数据段:存放程序中用到的各种全局变量或静态数据。
目标文件一般有三种类型:
- 可重定位文件
其中包含有:适合于其它目标文件链接来创建一个可执行的或者共享的目标文件的代码和数据。
- 共享的目标文件
这种文件存放了适合于在两种上下文里链接的代码和数据。
第一种是链接程序:可把它与其它可重定位文件及共享的目标文件一起处理来创建另一个目标文件;
第二种是动态链接程序:将它与另一个可执行文件及其它的共享目标文件结合到一起,创建一个进程映象。
- 可执行文件
它包含了一个可以被操作系统创建一个进程来执行之的文件。汇编程序生成的实际上是第一种类型的目标文件。对于后两种还需要其他的一些处理方能得到,这个就是链接程序的工作了。
语法:
-
[ gcc -c 文件名.c ] 执行.c文件至汇编停止🛑,生成默认同名的.o文件(目标文件)
-
[ gcc -c 文件名.s ] 在已有汇编文件的情况下,直接汇编处理.s文件,并默认输出同名.o文件。
-
[ gcc -c 文件名.c -o 文件名.o ] 汇编完成后,生成自己指定的.o文件。
-
[ od 文件.o] 二进制查看指令,查看.o文件的二进制码。
注意:面对多文件时,预处理
-E
,编译-S
,汇编-c
选项 就不能同时使用-o
了。但是直接运行时,多文件还是支持
-o
选项,这样可支持分离编译的需求。汇编生成的二进制文件并不能直接运行,因为没有链接,无法和库建立关联。
链接 ◉
功能:将我们自己代码中的函数调用,外部数据和库关联起来。
语法:
-
[ gcc 文件名.o ] 对目标文件执行链接
-
[gcc 文件名.c ] 对.c文件预处理(.i)->编译(.s)->汇编(.o)->链接,一步到位。默认生成a.out。也可添加
-o
选项,自己指定结果文件。 -
[ ldd 可执行文件 ] 查看可执行文件依赖哪些第三方库
Linux中,
静态库:.a文件,用于静态链接
动态库:.so文件,用于动态链接
静态链接:将库中的有关代码拷贝进自己的可执行程序中。(不再需要使用任何库)
动态链接:使用共享的第三方库,当库不存在,可执行文件便不可执行。
gcc默认生成的可执行文件为动态链接
-
[ gcc 文件名.c -o 目标文件名 -static ] 添加
-static
选项将生成静态链接的可执行文件。如果发生下面报错,说明当前环境没有安装静态库。
在新版本的linux 系统下安装 glibc-devel、glibc和gcc-c++时,都不会安装libc.a. 只安装libc.so , 所以当使用-static时,libc.a不能使用。
解决方法
安装 glibc-static
- [ sudo yum install glibc-static ]
静态库已安装,
再执行生成静态可执行文件:
静态链接的可执行程序占用空间更大,但可移植性更好。动态链接的可执行程序虽然更小,但如果丢失库,便无法执行。
-
[g++ -v] 查看 g++ 编译器的版本信息
g++ 与 gcc的选项几乎完全一致
4. Linux调试器——gdb的使用
GDB(GNU Debugger) 是gcc的调试工具,功能强大:
程序的发布有 debug
和 release
两种模式,
而Linux gcc/g++默认执行出来的二进制程序是 release
模式。
但是gdb无法对release
版本的二进制文件进行调试
如果要使用gdb调试,需进入 debug
模式,在源代码生成可执行程序的时候添加 -g
选项。
- [ gcc -g mytest.c -o mytest ]
- [ g++ -g mytest.cpp -o mytest ]
✔tips✔:如果一个程序是可以调试的,该程序的二进制文件一定加入了一些debug信息。(debug版本会比release版本更大一些)
-
[ readelf 选项 文件名] 查看
elf格式文件
(二进制文件,可执行文件,目标文件和库文件等)的信息(段信息),选项将控制显示哪一部分的信息。- -a 显示全部信息
- -h 显示elf文件开始的文件头信息
- -S 显示节头信息
- -g 显示节组信息
- -V 显示版本段的信息
查看
debug
版本文件的调试信息:release
是没有的。
语法:
-
[ gdb 可执行文件 ] 对该文件进入gdb调试,注意该文件一般在当前目录下。
-
[ gdb ] 直接进入gdb调试器
先贴上我准备调试的代码:
🛠进入gdb
-
[file 可执行文件] 调试此文件
-
[ list ],[ l ] 显示文件源代码 ,接着上次的位置往下显示代码,默认每次显示10行。
-
[ list n ],[ l n ] 从第n行开始显示源代码。
-
[ l 函数名 ] 显示函数的上下文
-
[ breakpoint n ],[ break n ],[ b n ] 在第n行设置断点
-
[ b 函数名 ] 将断点打在函数的第一条语句
-
[ info b ] 显示所有断点信息
-
[d 断点编号],[delete 断点编号] 删除断点
-
[delete] [d] 删除所有断点
-
[enable 断点编号] 启用断点
-
[disable 断点编号] 禁用断点
✔tips✔:可跟多个编号,对多个断点执行操作
-
[run],[r] 开始连续运行(至结束,或至第一个断点处),而非单步调试。
-
[ step ],[ s ] 逐语句调试,进入函数调用。
-
[ next ],[ n ] 逐过程调试。
-
[ display 变量 ] 跟踪监视变量 常显示
-
[ P 变量 ],[ p 变量 ] 查看某个变量的值,只显示一次,不会在后续的调试中常显示。
-
[ undisplay 变量编号n ] 取消对n号变量的跟踪监视
-
[ bt ],[ breaktrace ] 查看函数的调用堆栈情况
-
[ set var 变量=x] 在调试中修改变量的当前值
⭐快速跳转:finish continue until
-
[ finish ] 执行到当前的函数返回,然后停止🛑等待命令。
-
[ continue ],[ c ] 不断继续执行调试,至下一个断点或结束为止。
-
[ until n] 从当前位置开始, 无视途径断点,一路调试执行至n行(包含第n行),停在n+1行。(有些gdb会停在n行,自己试下就行)
⚠注意:按回车会重复执行上一条指令
- [ quit ],[ q ] ,ctrl+d : 退出gdb调试。
5. Linux项目自动化构建工具——make/Makefile
简介
一个工程的源文件数不胜数,其按照类型,功能分放在不同的目录中, Makefile 定义了一系列规则来指定哪些文件先编译,哪些文件之后编译,哪些文件需重新编译,以及进行更复杂的操作。
Makefile
带来的好处就是自动化编译,写好文件的处理关系之后,仅需一个 make
指令,整个工程就能按照Makefile
中的文件处理规则自动编译,极大提高了开发效率。
make 是指令工具,用来解释 Makefile 中的规则。一般来说大多数IDE都有这个指令,如Visual C++中的 nmake ,Delphi的 make ,Linux下GNU的 make 。可见 make/makefile 是常见的工程文件编译处理方法。
make是指令,Makefile是文件,两者搭配可完成项目自动化构建。
使用
这里贴上陈皓前辈关于make/Makefile使用的总结,写的很好,值得一看!
示例:
edit : main.o kbd.o command.o display.o insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit main.o kbd.o command.o display.o insert.o search.o files.o utils.o
总结:
-
一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。
-
在链接程序时,链接器会在所有的Object File中找寻所有声明的实现。
-
Makefile规则:
1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。
总结:
-
make规则(类似于一个堆栈的过程)
-
Makefile中统一管理变量(.o文件)——“$(objects)”
-
让make自动推导:
whatever.o文件可以自动找到同名.c(其他头文件需自己另行添加至依赖关系),而且可以自动推理出
gcc -c whatever.c
。⚠ 推理不会自行添加
-g
,如需要debug,还是要自己写。 -
clean
总结:
-
Makefile 里有什么?(显示规则,隐晦规则,变量定义$,注释,文件指示<其他Makefile,有效成分,多行命令>)
-
Makefile的文件名 (-f --file)
-
引用其他Makefile
include filename
filename可以是当前操作系统Shell的文件模式(可以包含路径和通配符)
在include前面可以有一些空字符,但是绝不能是[Tab]键开始。include和 filename 可以用一个或多个空格隔开。举个例子,你有这样几个Makefile:a.mk、b.mk、c.mk,还有一个文件叫foo.make,以及一个变量$(bar),其包含了e.mk和f.mk,那么,下面的语句:
include foo.make *.mk $(bar)
等价于:
include foo.make a.mk b.mk c.mk e.mk f.mk
-
make的工作方式
- 读入所有的Makefile
- 读入被include的其他Makefile
- 初始化文件中的内容
- 推导隐晦规则,并分析所有规则
- 为所有的目标文件创建依赖关系链
- 根据依赖关系决定先生成哪些目标,以及决定哪些目标要重新生成
- 执行生成命令
总结:
-
书写规则
Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来,第一条规则中的目标将被确立为最终的目标。如果第一条规则中的目标有很多个,那么,第一个目标会成为最终的目标。
-
规则的语法
-
在规则中使用通配符
🚩
*
?
[...]
举例
object = *.o
上面这个例子,表示了通配符同样可以用在变量中。并不是说 [ * . o ] 会展开,不!objects的值就是“*.o”。Makefile中的变量其实就是C/C++中的宏。如果你要让通配符在变量中展开,也就是让objects的值是所有 [ .o ]的文件名的集合,那么,你可以这样:
objects := $(wildcard *.o)
wildcard是关键字,之后会提。
-
文件搜寻
-
VPATH
-
vpath,%
- 伪目标
一些实例
文件和文件之间的相互依赖关系:编译源文件的先后关系,说明他们之间的关系是如何维护的。
makefile :指出 依赖关系 和 依赖方法
make+makefile:达到我们形成可执行文件的目的。
实例:
创建Makefile文件,vim进入
-
添加依赖关系
[目标文件:源文件]:目标文件将依赖源文件生成(顶格写)。
-
添加依赖方法
换行tab后开始书写,方法是多种多样的。
此处表明须有g++编译mytest.cpp生成mytest。
[ make ]:
生成解决方案和清理解决方案
[.PHONY] 总是可执行的,系统不会管你是不是最新的,可反复执行。
生成目标文件也可以用此修饰
但是生成目标可执行程序不建议这么修饰,因为只要原文件没有被修改,就没有必要浪费时间去重新编译了!
make在自顶向下扫描Makefile文件的时候,make指令会默认只会形成一个目标依赖关系(第一个)
clean在是第一个,make默认执行此依赖关系。
所以一般建议将生成写在最前面。
6. git的使用
在gitee新建好仓库之后,复制url
在linux环境中,选定仓库安放的文件夹,将仓库克隆到新目录中
- [ git clone url ]
将代码复制到仓库中,
查看工作树状态
- [ git status ]
代码上传三板斧:add commit push
先将将代码复制到仓库中
- add
- [ git add 文件名 ] 上传指定文件
- [ git add . ] 上传仓库中的所有文件
- commit
-
[ git commit -m “日志信息” ]
⚠注意:-m “日志信息” 不能缺省必须要添加上。
如果出现以下报告
需要执行蓝色方框的指令,表明身份。
其中
“you@example.com” 是 “注册手机号@gitee.com” 或者 “注册邮箱”
“Your Name” 是 “你的账户ID”
此时再次git commit 便可以了
- push
- [ git push ]
按提示输入账户ID和密码,即可上传代码至云端仓库。
-
查看git日志
[ git log ]
-
gitignore
配置文件,在此文件中出现的后缀格式的文件将不会被上传至仓库