Linux工具

目录

一、Linux软件包管理器yum

什么是yum?

查看软件包

如何安装软件?

如何卸载软件?

二、Linux编辑器——vim的使用

1、vim的三个常用模式

2、vim的基本操作

3、命令模式下的各种命令

4、底行模式命令

实用操作——批量注释与取消

三、Linux编辑器——gcc/g++的使用

gcc/g++使用的翻译场景

常用选项:

预处理

编译

汇编

链接

总结一下动静态链接的优缺点

四、Linux调试器——gdb的使用

1、背景

2、开始使用

3、常用调试命令:

五、Linux项目自动化构建工具—make/Makefile

背景

依赖关系和依赖方法

六、Linux小程序——进度条

回车换行(\n)的概念

缓冲区刷新机制

编写进度条


一、Linux软件包管理器yum

我们在Linux下有一般有三种软件安装方式

1、源码安装

2、rpm安装(安装包)

3、yum安装

我们一般都推荐yum安装,因为前者安装比较麻烦,可能存在大量的软件之间的依赖关系,(比如说,我们软件需要更新管理,想要下载新版本的就很麻烦)

什么是yum?

说简单明了:就是Linux下的应用市场

英文缩写:yum=Yellow dog Updater, Modified 。

主要功能是更方便的添加/删除/更新RPM包,它能自动解决包的倚赖性问题,它能便于管理大量系统的更新问题

注意事项:

关于yum的所有操作必须保证网络畅通,可以通过ping指令验证

[sjj@VM-20-15-centos ~]$ ping www.baidu.com

现在处于联网的状态了!!!

查看软件包

通过yum list我们可以查看一共有哪些软件包,可以利用grep筛选想要的软件包

yum list | grep lrzsz

查看结果:

注意事项:

1、软件包名称: 主版本号.次版本号.源程序发行号-软件包的发行号.主机平台.cpu架构.

2、"x86_64" 后缀表示64位系统的安装包, "i686" 后缀表示32位系统安装包. 选择包时要和系统匹配.

3、"el7" 表示操作系统发行版的版本. "el7" 表示的是 centos7/redhat7. "el6" 表示 centos6/redhat6.

4、最后一列, os 表示的是 "软件源" 的名称, 类似于 "小米应用商店", "华为应用商店" 这样的概念.

如何安装软件?

通过yum,我们就可以通过很简单的一条命令自动完成安装,需要sudo提升临时权限

sudo yum install lrzsz

yum会自动找到都有哪些软件包需要下载,这时候敲击“y”确认安装,出现“complete”说明安装完成

注意事项:

1、因为一般安装时需要向系统目录写入内容,一般需要sudo或者切换到root用户

2、yum一次只能安装一款软件,如果同时安装多个软件,会发生报错 

如何卸载软件?

任然是yum命令,同样需要提升权限 

sudo yum remove lrzsz

Linux与windows之间文件传送

Windows 上传到 Linux  :  rz + Enter(回车)

Linux 下载到 Windows : sz + 文件名 + Enter(回车)

二、Linux编辑器——vim的使用

vim在键盘上的键位

vim是一个Linux下的文本编辑器,可以类比Windows下的记事本

1、vim的三个常用模式

①命令模式(Normal mode)

②插入模式(Insert mode)

③底行模式(Last line mode)

2、vim的基本操作

①进入vim

输入vim后跟文件名,进入vim的命令模式,需要输入指令切换模式

vim test.c

②正常模式切换至插入模式

刚刚进入就可以敲击a,i,o切换

a
i
o

③插入模式切换至命令模式

处于插入模式时,就只能一直输入文字,像我们的记事本一样在里面输入。我们想要回退到命令模式,需要按左上角的Esc键

④命令模式切换至底行模式

按shift+:

⑤退出vim及保存文件

在命令模式,进入底行模式,输入

: w(保存当前文件)
: wq (输入wq,存盘并退出vim) 
: q! (输入q!,不存盘强制退出vim)

3、命令模式下的各种命令

插入模式

①按「i」切换进入插入模式「insert mode」,按“i”进入插入模式后是从光标当前位置开始输入文件;

②按「a」进入插入模式后,是从目前光标所在位置的下一个位置开始输入文字;

③按「o」进入插入模式后,是插入新的一行,从行首开始输入文字。

从插入模式切换到命令模式

按「ESC」键。

移动光标

①vim可以直接用键盘上的光标来上下左右移动,但正规的vim是用小写英文字母「h」、「j」、「k」、 「l」,分别控制光标左、下、上、右移一格

②按「G」:移动到文章的最后

③按「 $ 」:移动到光标所在行的“行尾”

④按「^」:移动到光标所在行的“行首”

⑤按「w」:光标跳到下个字的开头

⑥按「e」:光标跳到下个字的字尾

⑦按「b」:光标回到上个字的开头

⑧按「#l」:光标移到该行的第#个位置,如:5l,56l

⑨按[gg]:进入到文本开始

⑩按[shift+g]:进入文本末端

⑪按「ctrl」+「b」:屏幕往“后”移动一页

⑫按「ctrl」+「f」:屏幕往“前”移动一页

⑬按「ctrl」+「u」:屏幕往“后”移动半页

⑭按「ctrl」+「d」:屏幕往“前”移动半页

删除文字

①「x」:每按一次,删除光标所在位置的一个字符

②「#x」:例如,「6x」表示删除光标所在位置的“后面(包含自己在内)”6个字符

③「X」:大写的X,每按一次,删除光标所在位置的“前面”一个字符

④「#X」:例如,「20X」表示删除光标所在位置的“前面”20个字符

⑤「dd」:删除光标所在行

⑥「#dd」:从光标所在行开始删除#行

复制

①「yw」:将光标所在之处到字尾的字符复制到缓冲区中。

②「#yw」:复制#个字到缓冲区

③「yy」:复制光标所在行到缓冲区。

④「#yy」:例如,「6yy」表示拷贝从光标所在的该行“往下数”6行文字。

⑤「p」:将缓冲区内的字符贴到光标所在位置。注意:所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能

替换

①「r」:替换光标所在处的字符。

②「R」:替换光标所到之处的字符,直到按下「ESC」键为止。

撤销上一次操作

①「u」:如果您误执行一个命令,可以马上按下「u」,回到上一个操作。按多次“u”可以执行多次回复。

②「ctrl + r」: 撤销的恢复

更改

①「cw」:更改光标所在处的字到字尾处

②「c#w」:例如,「c3w」表示更改3个字

跳至指定的行

①「ctrl」+「g」列出光标所在行的行号。

②「#G」:例如,「15G」,表示移动光标至文章的第15行行首。

4、底行模式命令

在使用底行模式前,请一定记住先按Esc确认你已经处于命令模式中,再按shift+:进入底行模式

列出行号

「set nu」: 输入「set nu」后,会在文件中的每一行前面列出行号。

跳到文件中的某一行

「#」:「#」号表示一个数字,在冒号后输入一个数字,再按回车键就会跳到该行了,如输入数字15,再回车,就会跳到文章的第15行。

查找字符

「/关键字」: 先按「/」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直按 「n」会往后寻找到您要的关键字为止。

「?关键字」:先按「?」键,再输入您想寻找的字符,如果第一次找的关键字不是您想要的,可以一直 按「n」会往前寻找到您要的关键字为止。

保存文件

「w」: 在冒号输入字母「w」就可以将文件保存起来

离开vim

「q」:按「q」就是退出,如果无法离开vim,可以在「q」后跟一个「!」强制离开vim。

「wq」:一般建议离开时,搭配「w」一起使用,这样在退出的时候还可以保存文件。

实用操作——批量注释与取消

批量注释:

在命令模式下,Ctrl + v 进入块选择模式,然后移动光标选中你要注释的行,再按大写的 I (可以按住shift键加小写的i)进入行首插入模式输入注释符号如 // 或 #,输入完毕之后,按两下 ESC,Vim 会自动将你选中的所有行首都加上注释,保存退出完成注释

取消注释:

在命令模式下,Ctrl + v 进入块选择模式,选中你要删除的行首的注释符号,注意 // 要选中两个,选好之后按 d 即可删除注释,ESC 保存退出。

三、Linux编译器——gcc/g++的使用

gcc/g++使用的翻译场景

1、预处理(头文件的展开,宏替换,去注释)

2、编译(生成汇编代码)

3、汇编(生成二进制指令)

4、链接(生成可执行的文件或者库文件)

gcc/g++语法格式

gcc [选项] 要编译的文件名 [选项] 目标文件名

常用选项:

①-E,开始进行程序的翻译,完成预处理后,停下来,你需要把它生成的内容重定向到一个输出文件里面(否则将把预处理后的结果打印到屏幕上)。

②-S,开始进行程序的翻译,完成编译后,停下来

③-c,开始进行程序的翻译,完成汇编后,停下来

④-o,将处理结果输出到指定文件,该选项后需紧跟输出文件名

我们可以用一个已经写好的c源文件,来详细解读

预处理

gcc -E mytest.c -o mytest.i

预处理功能主要包括宏定义,文件包含,条件编译,去注释等。

预处理指令是以#号开头的代码行。

选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。

选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序

编译

gcc -S mytest.i -o mytest.s

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做工作,在检查无误后,gcc 把代码翻译成汇编语言。

用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

汇编

gcc -c mytest.s -o mytest.o

汇编阶段是把编译阶段生成的“.s”文件转成目标文件

读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了

链接

gcc mytest.o -o mytest
在成功编译之后 , 就进入了链接阶段

实际使用中并不用四步都执行,太繁琐了,咱们只需要执行第四步,编译器会自动帮我们完成前三个步骤:

gcc test.c -o hhh(名字可以自定)

在这里涉及到了一个重要的概念:函数库

问题:我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

答案:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用

语言也是有库的!!!一般由一套头文件+一套库文件组成(libc.a,libc.so)

需要链接来将我们自己写的代码中的函数调用起来,将外部数据和库关联起来

函数库一般分为静态库和动态库

静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”

动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件

③gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证

可以通过file命令来查看文件的类型: 

可以通过ldd命令来查看依赖的第三方库:

虽然gcc默认是动态链接的,但是我们可以加上-static选项,来让其静态链接

gcc mytest.c -o mytest_static -static

我们同样可以用fileldd命令来查看是否是静态链接的:

总结一下动静态链接的优缺点

静态库:

优点是,在编译后的执行程序不再需要外部的函数库支持,运行速度相对快些;

缺点是,如果所使用的静态库发生更新改变,你的程序必须重新编译。

动态库 :

优点是,动态库的改变并不影响你的程序,所以动态函数库升级比较方便;

缺点是,因为函数库并没有整合进程序,所以程序的运行环境必须提供相应的库

gcc的常用参数

选项含义
-I directory (大写的 i)指定 include 包含文件的搜索目录
-g在编译的时候,生成调试信息,该程序可以被调试器调试
-l 小写的l在程序编译的时候,指定使用的库
-L指定编译的时候,搜索的库的路径。
-fPIC/fpic

生成与位置无关的代码

-shared生成共享目标文件。通常用在建立共享库时
-std指定 C 方言,如:-std=c99,gcc 默认的方言是 GNU C

 -I的使用

 

我们现在把head.h放到一个include目录下:

 

gcc和g++的区别 

1、在代码编译阶段(第二个阶段):

后缀为 .c 的,gcc 把它当作是 C 程序,而 g++ 当作是 C++ 程序
后缀为.cpp 的,两者都会认为是 C++ 程序,C++ 的语法规则更加严谨一些
g++ 会调用 gcc,对于 C++ 代码,两者是等价的,也就是说 gcc 和 g++ 都可以编译 C/C++ 代码

2、在链接阶段(最后一个阶段):

gcc 和 g++ 都可以自动链接到标准 C 库
g++ 可以自动链接到标准 C++ 库,gcc 如果要链接到标准 C++ 库需要加参数 -lstdc++

3、关于 __cplusplus 宏的定义

g++ 会自动定义__cplusplus 宏,但是这个不影响它去编译 C 程序

gcc 需要根据文件后缀判断是否需要定义 __cplusplus 宏 (规则参考第一条)

四、Linux调试器——gdb的使用

1、背景

在Windows下的vs编译器中,程序的发布方式一般有两种,debugrelease两个模式

因为Linux下gcc/g++翻译出来的是二进制的程序,默认是release模式,所以要使用gdb调试,必须在生成的源代码中生成二进制的时候,加入一些调试信息,我们需要加上 -g选项

 我们可以敲击readelf -S mytest来查看程序的段构成:

段构成其实就是我们程序是由哪些数据段组成的,是由堆区上的数据,还是常量区的,还是栈区等等区域,我们通过翻阅查找,并没有看到debug相关的信息!!

我们知道如果一个程序可以被调试,该程序中的二进制文件一定加入了一些debug信息!而release中则没有debug信息!

所以我们需要在生成可执行程序的时候加入一些debug信息(这里我们只需要加入了可调试的信息,不用具体深究到底是什么) 

[sjj@VM-20-15-centos 2022_3_18]$ gcc mytest.c -o mytest -g

 我们再次查看程序的段结构:

[sjj@VM-20-15-centos 2022_3_18]$ readelf -S mytest | grep -i debug

总结: 所以gdb要调试程序必须是debug方式发布的,也就是要加gcc -g选项

2、开始使用

语法:gdb +可执行程序名      退出:ctrl+d或者quit

3、常用调试命令:

①list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。

②r或run:运行程序。

③n 或 next:单条执行。

④s或step:进入函数调用

⑤break(b) 行号:在某一行设置断点

⑥info break :查看断点信息。

⑦print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数

⑧p 变量:打印变量值。

⑨set var:修改变量的值

⑩continue(或c):从当前位置开始连续而非单步执行程序

⑪run(或r):从开始连续而非单步执行程序

⑫delete breakpoints n:删除序号为n的断点

⑬disable breakpoints:禁用断点

⑭enable breakpoints:启用断点

⑮info(或i) breakpoints:参看当前设置了哪些断点

⑯display 变量名:跟踪查看一个变量,每次停下来都显示它的值

⑰until X行号:跳至X行

⑱quit:退出gdb

五、Linux项目自动化构建工具—make/Makefile

背景

1、make是一个命令,而Makefile是一个文件

2、我们在写一些大型的项目或者工程时候,上百个源文件、头文件等都在不同的目录中放着,我们想要把这些文件组织起来就相当的麻烦,难道我们要将他们一个一个的gcc编译成可执行程序,删除的时候在一个一个的删除?万一中途不小心打错一个?这样显得太过于繁琐了

3、Makefile里面包含依赖关系和依赖方法,一起配合就可以实现自动化编译,一旦将命令写好,只需要一个make命令,整个工程完全自动化编译,删除的时候,直接一个make clean命令,就直接删除了,不用重复敲击rm...命令,极大的提高了软件开发的效率!!!

依赖关系和依赖方法

依赖关系

我们知道mytest可执行程序的生成,必须要先有mytest.c这个源程序,这里我们就可以说mytest依赖于mytest.c

依赖方法

就是生成mytest可执行程序的方法,我们就称为依赖方法,例如:

[sjj@VM-20-15-centos 2022_3_18]$ gcc mytest.c -o mytest

C代码示例:

先创建一个名为Makefile的文件

再在里面编写依赖关系和依赖方法

 我们现在可以直接敲击make命令,执行依赖方法

我们可以直接 ./ 运行一下可执行程序,观察效果

问题来了:

问题一:为什么我们敲击make就可以直接执行,而清理需要make+clean呢?

原因:make扫描Makefile文件时,默认只会形成一个目标依赖关系,一般是第一个

问题二:为什么要加一个 .PHONY 这样的符号?

原因:修饰对应的符号,这是一个伪目标的概念,(其实就是总是可以执行的意思)

简化写法:

其中的$@ 就是目标文件(冒号左边的),$^就是依赖的文件(冒号右边的),敲击make运行时会自动转换为上面的文件

其实make和make clean可以类比vs中的生成和清理解决方案:

六、Linux小程序——进度条

回车换行(\n)的概念

回车(\r):就是回到当前行的首位置

换行:列不变,换到下面一行

我们先来观察两段代码:有什么现象呢?

#include <stdio.h>
int main()
{
 printf("hello\n");
 sleep(3);
 return 0;
}
#include <stdio.h>
int main()
{
 printf("hello");
 sleep(3);
 return 0;
}

我们会发现,带了\n的会立即将hello打印出来然后等待3秒钟结束程序,而不带\n的则需要等待3秒才能显示出来,那么问题是不是sleep函数执行先于printf函数呢?其实不是,printf函数已经执行,但是数据存放起来了,并没有立即刷新到屏幕上面去

缓冲区刷新机制

所以我们需要介绍我们的缓冲区机制(遇到\n进行刷新)

但是我们现在不想带上\n却也想将缓冲区给刷新,我们就要用到fflush函数了

int fflush(FILE *stream);
#include <stdio.h>
#include<unistd.h>
int main()
{
	printf("hello");
	fflush(stdout);
	sleep(3);
	return 0;
}

这样程序直接就打印在了屏幕上了

有了这些前置基础,就可以开始写进度条程序了。

编写进度条

特点:我们的目标就是在屏幕上面,肉眼可见的不断变长的进度条,顺便带上些许提示。

#include<stdio.h>
#include<unistd.h>
#include<string.h>
int main()
{
	int i = 0;
	char bar[102];//0到100的一个字符串,最后加个\0
	memset(bar, 0, sizeof(bar));
	const char* lable = "|/-\\";//提示加载标签
	while (i <= 100)
	{
		printf("[%-100s][%d%%][%c]\r", bar, i, lable[i % 4]);
		fflush(stdout);
		bar[i] = '#';
		i++;
		usleep(50000);
	}
	printf("\n");
	return 0;
}

我们设置了一个字符数组,来存放我们的'#',通过将其不断的加长,每次将这个字符串打印在屏幕上,不换行,只回车,来实现我们的进度条:

为了美观,可以适当的改变字体的颜色,甚至加一些个性化的设置,可以百度搜索更多! 

  • 33
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 59
    评论
评论 59
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值