文章目录
- 1.yum
- 1.1 yum是什么?
- 1.2yum下载的软件包在哪?
- 1.3 yum的配置
- 1.4 yum的相关操作
- 2. Vim
- 2.1 各种模式的相关操作
- 2.2 利用vim解决普通用户无法sudo的问题
- 2.3 vim的配置
- 3.gcc/g++
- 3.1 利用gcc理解程序的翻译过程
- 3.2 编译器的自举
- 4. 程序的链接
- 4.1动态链接
- 4.2静态链接
- 5. make/makefile
- 5.1makefile的编写
- 5.2makefile的原理
- 6.Linux工具的综合使用
- 6.1 倒计时小程序
- 6.1.1 缓冲区
- 6.1.2 代码实现
- 7. git和github
- 7.1 git是什么
- 7.2 git的起源
- 7.3 git的操作
- 8.gdb
- 8.1 release和debug的区别
- 8.2 gdb的操作
1.yum
1.1 yum是什么?
简单点讲,yum类似于我们手机上的应用商店;刚买的手机想要下载软件,一般都是从应用商店下载;同样的,在Linux想要下载东西,最常见的方式就是借助yum进行下载安装;同时,我们下载的软件可能需要依赖其他软件才能正常使用,yum在下载这类软件时会帮助我们解决这些问题
1.2yum下载的软件包在哪?
我们在手机上要下载的软件包是不是原本就在手机上?答案是否定的,在Linux中也是如此,想要下载的软件包在机器的远程服务器上,yum通过本地的yum源找到远程服务器,再在服务器中找到对应的软件包,下载到本地机器,再安装下来
Linux中,yum源通常有两种:
- base源(基本软件源):这里面的软件基本是稳定的
- epel源:扩展软件源,这里面的软件的稳定性是不确定的
两种源的路径保存在Linux中的【/etc/yum.repos.d】路径下
这两个配置文件中存储着下载链接,当使用yum下载软件时,会根据配置文件中的下载链接找到对应的下载地址,再进行软件下载;
但配置文件中的下载链接通常是在国外的,有时下载速度慢,这就需要我们修改yum的配置文件;其本质是更改软件下载链接
1.3 yum的配置
进入到本地yum仓库中
cd /etc/yum.repos.d
备份本地yum源
mv CentOS-Base.repo CentOS-Base.repo.bak
下载阿里yum源
wget http://mirrors.aliyun.com/repo/Centos-7.repo
将阿里yum源改名为Linux系统默认读取的yum源
mv Centos-7.repo CentOS-Base.repo
加载阿里yun源
yum clean allyum makecacheyum update
1.4 yum的相关操作
yum的基本操作有三种
- 下载并安装**【yum [-y] install xxx】**
- 卸载**【yum [-y] remove xxx】**
- 查找**【yum list | grep xxx】**
2. Vim
vim是一款多模式的文本编辑器,经常使用的有三种模式:
- 命令模式
- 插入模式
- 底行模式
2.1 各种模式的相关操作
插入模式:用来正常的编写代码
命令模式:通过命令进行文本的编辑
n+yy #复制光标所在的行,n表示复制下面的n行 n+p #粘贴,n表示粘贴n次 u #撤销 ctrl+r #对撤销进行撤销 n+dd #剪切光标所在行,n表示剪切下面的n行 shift+4 #将光标定位到当前行的结尾 shift+6 #将光标定位到当前行的开头 gg #将光标定位到整个文本的开头 shift+g #将光标定位到整个文本的结尾 n+shift+g #将光标定位到第n行 h,j,k,l #左,下,上,由 w #以单词为单位进行光标后移 b #以单词为单位进行光标前移 shift+` #大小写快速转换 n+x #删除光标后的n个字符 n+shift+x #删除光标前的n个字符 n+r #对光标所在字符进行替换,可以n个字符替换 shift+r #进入替换模式 shift+zz #保存并退出
底行模式:可以实现vim与shell交互
w #保存 q #退出 wq #保存并退出 ! #强制 set nu/nonu #显示行号 !command #不退出vim执行Linux命令 vs filename #分屏 /xxx #搜索 ctrl+w #分屏中切换屏幕
再额外介绍几个操作
v #进入视图模式
v+hjkl+d #批量截切
v+hjkl+y #批量复制
ctrl+v #进入块视图模式
[ctrl+v]+[hjkl]+[shift+i]+[//]+[esc] #批量注释
[ctrl+v]+[hjkl]+d #批量去注释
2.2 利用vim解决普通用户无法sudo的问题
我是一名普通用户,在某些特殊情况需要指令提权才能执行相关操作;在Linux中允许我们这样做,但前提是该普通用户在root的sudoers列表当中,学会了vim的基本操作,我们就可以添加用户到sudoer是列表中了
- 使用vim打开sudoers文件,必须是root用户,因为普通用户对sudoers文件没有任何权限
vim /etc/sudoers
- 在文本的100左右按照root的格式添加要加入的用户
- shift+:加入底行模式,wq!强制保存退出
2.3 vim的配置
在执行vim命令时,不光是执行vim这样一个可执行文件,还会去用户的家目录执行一个名为.vimrc的文件;配置vim的本质就是在.vimrc文件中添加想要的功能指令
.vimrc是在每个用户的家目录当中的,因此不同的用户,可以自己配置属于自己的vim
vim的一键配置:
在普通用户下,确保你的Linux系统是Centos7.6的,执行【curl -sLf https://gitee.com/HGtz2222/VimForCpp/raw/master/install.sh -o ./install.sh && bash ./install.sh】命令,即可一键配置vim
想要删除配置好的vim,在安装了VimForCpp的用户下执行【bash ~/.VimForCpp/uninstall.sh】命令即可
3.gcc/g++
gcc是一款用来编译以.c结尾的C语言文件的编译器;而g++是一款用来编译以.cpp/.c/.cxx结尾的c++文件的编译器
一般Linux系统中,gcc是系统默认就有的,只不过版本可能较低;g++需要我们自行安装
sudo yum -y install gcc-c++ #Linux中安装g++
3.1 利用gcc理解程序的翻译过程
我们知道,一个源代码文件需要经过编译和链接才能变成一个可执行程序,而编译又分为预编译,编译和汇编三步骤;知道了gcc,我们就可以验证三个步骤分别做了什么了
3.2 编译器的自举
最早期,机器只能识别二进制指令,科学家们觉得二进制不方便,于是使用了助记符来表示二进制;助记符的形式慢慢发展,变成了汇编语言;科学家是知道汇编代码代表的二进制指令,但由于没有汇编代码的编译器,机器是不认识汇编代码的,这样就必须有能将汇编代码转换成二进制代码的编译器才行;于是科学家用二进制代码写了一个编译器,能成功编译汇编代码,但由于还是使用的二进制代码,不够方便;此时有个问题,编译器是个软件,既然是个软件,就代表着能用代码进行编写,那能不能用汇编代码来编写一个编译器,用来翻译汇编代码呢?答案是可以的,因此科学家们就实现了这样的编译器,完成了编译器的进步;
向上面这种,编译器随着语言的进步而进步,叫做编译器自举的过程
为什么一个程序的翻译过程是预处理—>编译—>汇编—>链接呢?
在编译器自举的过程中讲到,二进制语言先发展成为汇编语言,再发展成为高级语言;由于机器只能看懂二进制语言,因此我们需要将高级语言翻译成二进制语言;此时有两种方案:
- 直接编写能将高级语言翻译成二进制语言的编译器
- 只需编写能将高级语言翻译成汇编语言的编译器即可,因为汇编语言翻译成二进制语言的技术已经有了
毫无疑问,肯定是选择第二种,这样不仅能降低编译器的开发难度,更是利用了前人留下的成果;因此,如今一个程序被翻译成二进制目标文件的过程是预处理—>编译—>汇编—>链接
4. 程序的链接
源代码经过预处理—>编译—>汇编形成的二进制目标文件需要经过链接才能被执行;链接的过程其实就是目标文件和库结合的过程;源代码中库函数的具体实现是在C标准库中,在Linux中,使用【ldd】命令可以查看一个可执行程序所需要的标准库
源代码中,我们包含需要库函数的头文件,在链接时,编译器就会去标准库中将源代码与头文件对应的源文件链接
链接方式有两种:
- 动态链接
- 静态链接
与动态链接对应的是动态库,与静态链接对应的是静态库;
在Linux和Windows中,动态库和静态库的文件后缀不同
Linux中:
- 动态库:xxx.so
- 静态库:xxx.a
Windows中:
- 动态库:xxx.dll
- 静态库:xxx.lib
4.1动态链接
gcc链接时默认采用动态链接的方式与标准库进行链接;在链接过程中,编译器会提供动态库的地址,将程序与动态库链接,这也就意味着,如果动态库弄丢了,程序就无法完成编译
4.2静态链接
相较于动态链接,静态链接会将标准库拷贝到程序当中;Linux中,默认没有下载静态库
sudo yum -y install gibc-static #静态库的下载gcc xxx -o xxx -staic #以静态链接的方式链接程序
动态链接的优缺点:
- 节省资源,所有程序共用一个动态库
- 一旦动态库弄丢了,所有程序都无法执行
静态链接的优缺点:
- 浪费空间,由于每一个程序都需要拷贝一份静态库,会消耗很多空间
- 程序链接后,不管有没有静态库,该程序都可以运行
5. make/makefile
make是一个命令,makefile是一个文件;执行make命令时,会去当前目录查找有没有makefile文件,如果有,会去执行makefile文件中的代码
make和makefile的应用场景:
- 每次使用gcc编译一个源文件时,都需要【gcc xxx -o xxx】,那如果有上百个源文件需要编译,难道对每个源文件都执行一次gcc指令,显然太麻烦了;而make/makefile就是一次性处理多个文件
5.1makefile的编写
利用make/makefile,我们要实现的功能是,使用【make】指令可以自动编译源文件;使用【make clean】指令自动帮我们清除项目
5.2makefile的原理
在使用【make指令】时,会在makefile文件执行遇到的第一个命令;同时,默认情况下,如果生成的目标文件是最新的,不会进行二次执行;根本原因是因为,编译一个程序是需要花费时间的;对于一个大工程,编译会花费很长时间,试想你好不容易编译好了文件,而如果不小心执行了【make】命令,就会再去浪费时间编译;因此make默认不会执行最新的文件
执行make指令后,怎么知道我的目标文件是最新的?
- 使用【stat】指令,可以看到文件的修改时间,【Modify time】,这个时间是文件内容被修改的时间;由于一定是先有源文件,才有对应的可执行程序,所以如果源文件是最新的,它的时间一定比可执行程序新;通过比较源文件和对应可执行程序的【Modify time】
- 如果源文件的时间更新,表示需要重新编译
- 如果对应可执行程序的时间更新,不会进行二次编译
对于编译源文件,我的确需要比较时间,防止程序被重复编译;但对于某些指令,比如清除杂项,我需要它总是被执行,这样比较时间对我来说就比较多余了,能不能再执行【make】指令时,不比较时间,让目标指令总是被执行?
在编写makefile时,可以对指令进行【.PHONY】修饰,这样目标指令就是总是被执行的状态了
如果我们写出详细的过程,发现依然能达成我们想要的结果,只不过多生成了几个文件
makefile会从上往下执行代码,如果某段代码没有对应的依赖文件,会暂时记录该代码,往下寻找对应的依赖文件,最后再依次返回,有点像递归的操作;但必须把最终的目标文件写在开头,因为makefile一旦找到一个能执行的代码,就只执行一次
当然,我们之后写makefile不可能这么复杂,我们可以写的更加简介
6.Linux工具的综合使用
6.1 倒计时小程序
6.1.1 缓冲区
代码1现在屏幕上打印,再休眠3秒;代码2先休眠3秒,再在屏幕上打印
造成这样结果的原因是什么?实际上,Linux中一切皆文件,我们的键盘,屏幕分别有着对应的键盘文件,显示器文件;而在内存中,这两个文件又有着对应的缓冲区,我们能在屏幕上看到数据,本质是缓冲区中的数据刷新到了显示器文件
有三种方式会刷新缓冲区:
- 遇到【\n】或者程序结束
- 缓冲区满了
- 使用fflush强制刷新缓冲区
为什么以【\n】作为刷新缓冲区的标志?想要在内存和文件之间传输数据,一次传输的数据量越多,传输的次数越少,传输的效率也就越高,而如果传输的数据过多,又不方便我们阅读,因此以行作为刷新缓冲区的标志是一种即提高效率,又方便阅读的做法
6.1.2 代码实现
7. git和github
7.1 git是什么
git是一款代码分布式管理工具,也可以叫做版本控制工具,由Linus Torvalds发明
7.2 git的起源
Linus Torvalds发布Linux系统后,收到了一大批关于Linux的代码,他需要不停的将这些代码组合在一起;有一天,他实在无法忍受了,想着有没有一款能帮我汇总代码的软件,他去市面上找,确实是有,但它收费,这与Linus Torvalds本人发布Linux时的理念相违背;可是软件的老板声称可以让他免费使用该软件,都到了这份情面上了,不用白不用;但好景不见风长,Linux社区中的某些人想着能不能破解该软件,但被软件老板知道了这件事,于是停止了给Linus Torvalds的软件免费使用权;既然不给我用,那干脆我就自己写一个代码管理的软件,这便是git的起源
通过git我们可以提交本地代码到远程仓库,下载相应客户端来查看仓库,但下载客户端又显得麻烦,于是就有了网站式的代码托管平台(github)
7.3 git的操作
首先在gitee或者github上创建好仓库,将远程仓库地址拷贝到Linux中,我们本地仓库就多了一些文件
8.gdb
8.1 release和debug的区别
我们都知道,市面上的软件一般有两个版本,release和debug,二者有什么区别呢?
一款软件经过测试没有问题后,面向用户发布的版本叫做release版本,它相对于debug版本做了一些优化,删除了调试信息,因此不能进行调试;当然,对于用户本就不需要调试,因此release版本删除调试信息是合理的,但对于程序员,调试就异常关键,而面向程序员发布的版本就叫做debug版本;由于debug版本加上了调试信息,因此在文件大小上会大于release版本
Linux中默认情况下使用gcc编译源文件产生的可执行程序是release版本,想要在编译的过程中加上调试信息,需要在gcc编译加上-g选项
8.2 gdb的操作
指令 | 作用 |
---|---|
list(简写为l)+行号/函数名 | 显示对应的源代码 |
b+文件名:行号/函数名 | 打断点 |
info(简写为i)+b | 查看断点 |
d+断点编号 | 删除断点 |
disable/enable+断点编号 | 使能(关闭/打开)断点 |
run(简写为r) | 运行程序 |
next(简写为n) | 逐过程 |
step(简写为s) | 逐语句 |
print(简写为p)+变量 | 查看变量内容或地址 |
display+变量 | 变量跟随 |
undisplay+变量编号 | 取消变量跟随 |
continue(简写为c) | 移动到下一个断点处 |
finish | 直接运行完当前函数停下来 |
until+行号 | 跳转至指定行 |
set var+变量 | 主动设置变量的值 |
info(i)+local | 查看当前栈帧的局部变量 |
bt | 查看函数调用关系 |
+变量 | 变量跟随 |
undisplay+变量编号 | 取消变量跟随 |
continue(简写为c) | 移动到下一个断点处 |
finish | 直接运行完当前函数停下来 |
until+行号 | 跳转至指定行 |
set var+变量 | 主动设置变量的值 |
info(i)+local | 查看当前栈帧的局部变量 |
bt | 查看函数调用关系 |