Linux环境基础开发工具使用(yum软件安装工具的使用、vim编辑器使用及握gcc/g++编译器的使用等下)

简介: 程序的发布方式有两种,debug模式和release模式

4.Linux调试器-gdb使用


4.1 背景


程序的发布方式有两种,debug模式和release模式

Linux gcc/g++出来的二进制程序,默认是release模式

要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项


4.2 开始使用


gdb binFile 退出: ctrl + d 或 quit 调试命令:

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

list/l 函数名:列出某个函数的源代码。

r或run:运行程序。

n 或 next:单条执行。

s或step:进入函数调用

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

break 函数名:在某个函数开头设置断点

info break :查看断点信息。

finish:执行到当前函数返回,然后挺下来等待命令

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

p 变量:打印变量值。

set var:修改变量的值

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

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

delete breakpoints:删除所有断点

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

disable breakpoints:禁用断点

enable breakpoints:启用断点

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

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

undisplay:取消对先前设置的那些变量的跟踪

until X行号:跳至X行

breaktrace(或bt):查看各级函数调用及参数

info(i) locals:查看当前栈帧局部变量的值

quit:退出gdb


4.3 理解


首先我们建立一个test.c文件,然后进行编译,代码如下:


c947139c28824686884693521e52b1d8.png


但是我们要知道的是,在gcc或g++环境下默认生成的是动态链接release可执行文件,也就是说,他无法进行调试

我们可以在编译时加上-g,即指令gcc test.c -o testdebug -g

我们可以通过readelf -S 文件名的方式来查看两个可执行文件有何不同

默认生成的test可执行文件readelf -S test


be5a6747e8a14df9bf47a3888c5ccda2.png


生成的debug文件readelf -S testdebug


5946dfc5f6884e92a2fccab719cbeece.png


可以看到第二个文件是包含调试信息的,而第一个没有,所以第二个文件才能使用gdb进行调试


第一步我们输入指令gdb testdebug开始调试


ba0ee71b2bea46f083603f3c330ac02c.png


需要注意的是gbd会记录最近一条命令,如果命令无变化,可以直接回车

比如我们先显示所有代码从头开始打印输入l 0


d05630301dac4c028d79319ed70cb220.png


输入指令b 行号打断点


383a3f05c79642f58e9ae8fbcf608924.png


输入指令info b查看断点


c269d094e4474c4e9ef784f83ebc3c09.png


输入指令d 断点编号删除断点,记住不是行号而是查看断点中的num编号


8d45470393a242b29ec55a1f659deb8c.png


然后我们输入指令r开始调试,如果没设置断点,则直接运行结束


2b4dafc5d7ef477e899341fed3c57402.png


然后我们在执行函数前打一个断点,输入指令s为逐语句,输入n为逐过程


14505ce0eb0e4747b2d58ca70c14d69e.png


输入指令bt查看当前调用堆栈


ee99cab793c3447f9fb386863271b5e4.png


输入指令p 变量名打印变量内容,或者指令p &变量名查看地址


58cc809d10404d198b621f34037a4e16.png


如果你想常显示输入指令display 变量名,取消常显示输入指令undisplay


ee204700a4f148f383e280747e534d41.png

61d719aae8254b17b9d83f208eb00535.png


输入指令finish当前函数直接跑完再停下来


13a233315f6a4ce6aa0c7a9eb3b2e3ee.png


或者还可以输入指令until 行号直接跳转到某一行


54090dd992a444499bc98e39a88433cf.png


再比如下面我们多打几个断点,执行命令c直接运行到下一个断点停下来


875e31f5286d449b85edd57bf60d63a1.png

37312647b9b24e869337249c98596180.png


执行命令disable/enable 断点编号能关闭/打开断点


ea70b122e1e94f36a697696e773ec07d.png


最后执行命令quit退出gdb调试工具


ee4dd612fda1401da6c12e23854ff634.png


所有基础gdb调试命令就这些啦!


5.Linux项目自动化构建工具-make/Makefile


5.1 背景


会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力


一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作


makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。


make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。


make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。


5.2 理解


首先我们先在c文件的同目录下建立一个Makefile文件(首字母大小写均可)

输入touch Makefile


d1264766fe774633b4e352b5b33a42a8.png


我们打开Makefile文件输入下面信息后保存退出


  1 tests:test.c
  2   gcc test.c -o tests 
  3 .PHONY:clean
  4 clean:
  5   rm -f tests


1ebe4797d7044f4981ecc6b8923dbaa8.png


这段代码中第一行test是我们自己定义的Makefile命令,指向test.c文件,其为依赖关系,只有执行对应的指令,才会执行相对应的依赖方法,第三行中的.PHONY为伪目标定义,使得clean命令可以重复执行。

下面我们看如何使用这两个makefile命令

如果我们直接输入make则直接默认执行第一条命令


fe6a818b720f4118bc6cd81868ae1659.png


当然我们也可以使用make tests


34b0b78f593742ae91f1f051da2e5dc2.png


我们再执行第二条命令make clean


cee3de7c81df4de5ac83b5ae2c02ec0a.png


在这里我们需要注意的是,如果重复使用第一条命令,则会出现下面的情况


96c69ff9d45442c1a3dac63cb7122e90.png


这是因为我们的tests文件修改时间晚于test.c文件,所以它默认tests文件不必重新生成


cbc6c8448fbb4c029b27a7e2b97f3fdb.png


如果我们对test.c文件进行修改,再调用第一条命令,则可以重新调用


626a26dec19640419a25d07c2429168b.png


可以看到此时test.c文件最近修改时间比tests文件要更晚,此时我们再调用make指令


46be2657da6c46fca7efcd04ac6b2bac.png


5.3 实例代码


首先我们建立三个文件,如下:

test.h


  1 #pragma once 
  2 #include<stdio.h>
  3 
  4 extern void show(); 


test.c


  1 #include"test.h"
  2 void show()
  3 {
  4   printf("hello linux!\n");                                                                                                                                                                                                      
  5 }   


code.c


  1 #include"test.h"
  2 
  3 int main()
  4 {
  5   show();                                                                                                                                                                                                                        
  6   return 0;                                                                                                            
  7 }  


我们再将Makefile文件修改一下,如下:


  1 test:test.o code.o
  2   gcc -o tests test.o code.o
  3 test.o:test.c
  4   gcc -c test.c -o test.o
  5 code.o:code.c
  6   gcc -c code.c -o code.o
  7 
  8 .PHONY:clean
  9 clean:
 10   rm -f *.o tests  


保存后退出

我们输入命令make


9a241fd2de8e4d6fab022b95f77ba6e5.png


执行命令make clean


e472234012ae4ad1b9336bbbeac20d02.png


最开始的test命令下对应的是两个.o文件,但是目录下并没有,那么它会继续向下寻找依赖关系,执行依赖方法。


5.4 原理


make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,


1.make会在当前目录下找名字叫“Makefile”或“makefile”的文件。

2.如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“tests”这个文件,并把这个文件作为最终的目标文件。

3.如果tests文件不存在,或是tests所依赖的后面的test.o及code.o文件的文件修改时间要比tests这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成tests这个文件。

4.如果tests所依赖的test.o和code.o文件不存在,那么make会在当前文件中找目标为test.o和code.o文件的依赖性,如果找到则再根据那一个规则生成test.o和code.o文件。(这有点像一个堆栈的过程)

5.当然,你的C文件和H文件是存在的啦,于是make会生成 test.o和code.o文件,然后再用 test.o和code.o 文件声明make的终极任务,也就是执行文件tests了。

6.这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。

7.在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。

8.make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。


5.5 项目清理


1.工程是需要被清理的

2.像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。

3.但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。

4.可以将我们的 tests 目标文件声明成伪目标,测试一下。


5.6 Linux第一个小程序-进度条


首先我们创建Makefile文件并进行编辑保存


  1 proc:proc.c
  2   gcc -o proc proc.c
  3 .PHONY:clean
  4   rm -f proc  


创建proc.c文件


#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
  int i = 0;
  char bar[102];
  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++] = '#';
    usleep(10000);
  }
  printf("\n");
  return 0;
}


保存好执行make


4d0b0ae670cd44929c979d6063ad7182.png


运行proc


9183f33028d8410d874fde5e4d571b54.gif


6.Linux上git的使用


首先我们在命令行输入git -v查看是否安装git


6d5c6652e2bf4cf1affcde62839271d9.png


若没有安装先执行sudo yum install -y git

因为作者使用的是GitHub托管代码,如果是gitee方法也大同小异

首先我们先建立一个项目仓库,用于测试


d17d975cf9d446e9afa7d024b274f76d.png


这两个选项都是用于建立新项目仓库


e7dd152ea77a495f8d77864f55e2b3b9.png


接下来我们拷贝该仓库的本地链接


8d3f271f96ef41aea6fd105d518f3628.png


下面我们回到Linux,进行第一步操作git clone 刚刚复制的仓库链接


0656d59ec2234d928d100d79210476de.png


接下来我们访问同名目录


c3d9bea76f7b4c5fa4d5e342d7b75048.png


现在我们可以将自己的代码上传,第一步上传代码到本地

git add test1.c

再写提交日志

git commit -m "这是一个测试代码"


58c0c69cc4d94157ada3b50498903935.png


再进行push上传,输入git push


1ab894cd66dd40c1a3eb83637a77e01d.png


需要注意的是,在push过程中,要输入用户名和密码,但是现在GitHub不支持密码方式push,所以我们需要创建一个令牌,用令牌代替密码即可成功push(getee用户不需要)


令牌设置


d5c3ef7d03ba408a84d6970408f29eaa.png


往下滑动可以找到


12e95da002974ef7809ccfea3c2db43c.png


因为我这是创建过的,所以可能有些不同,没创建过的应该只有一个按钮


483228a7f12e4bd2b7f5b8545c6a2091.png


有可能直接就是下面的页面


585852836a9042d48436a315ae59412e.png


3ee9687804e74e2fa95f4b347ae7c09b.png


记得复制好,放到记事本或者其他可以记录的地方,下一次进来就看不见了


a6d5679711e54c56b1877bba39531fdf.png


下次上传直接用这个令牌就行啦


d9aefac769634efea951f65266d7a444.png


c69096eddf1b4652be6e1f47f3e0b75f.png


还有一种其他的情况,如果在别的设备上我们更改了GitHub上该仓库内容,可能我们直接进行push会碰到下面的情况


43ec6d552da4437eb8aaa7227d22a1be.png


GitHub的仓库有了另一个文件,但是我的本地仓库并没有,此时我们建立一个新文件上传,看看会发生什么


9add226e290446ed9cd2a7691e8fa487.png


可以看到我们上传失败了,这是因为本地仓库和平台出现了不匹配的情况,也就是发生了冲突,这个时候我们直接无脑

git pull


268a4fcb1ebc4df4bfb663de127933d0.png


然后我们再进行上传


2d584ccba487464f94c347294aa5b656.png


d54c8ffb1dcf4023809a2f31ade62ce0.png


关于.gitignore文件我们可以自己进行编辑修改,主要目的就是在以目录文件形式上传时,过滤掉不需要的文件


b3fa3f513bca4d4d9545b4933ec2ce63.png

468de959c93f4dc9b2e0256269cf3d5e.png


我添加两个后缀名为.x和.X的信息,下面我们创建一个目录,包含一些文件


fd9f00fec24f45c493a682649be7c515.png


我们可以看到再进行commit命令时,本地已经将.x和.X文件忽略了


347119b1a3bc4e25b46fc6215fddc71b.png


我们再看GitHub仓库同样没有上传


7a1c6a9d5f99405ca83835e14f6dd4a7.png


结语


有兴趣的小伙伴可以关注作者,如果觉得内容不错,请给个一键三连吧,蟹蟹你哟!!!

Linux两万两千多字的文章,花了我很多时间和精力!!!

制作不易,如有不正之处敬请指出

感谢大家的来访,UU们的观看是我坚持下去的动力

在时间的催化剂下,让我们彼此都成为更优秀的人吧!!


21ac207e9eab42afad47043cd7b92dc9.png

相关实践学习
CentOS 7迁移Anolis OS 7
龙蜥操作系统Anolis OS的体验。Anolis OS 7生态上和依赖管理上保持跟CentOS 7.x兼容,一键式迁移脚本centos2anolis.py。本文为您介绍如何通过AOMS迁移工具实现CentOS 7.x到Anolis OS 7的迁移。
相关文章
|
2月前
|
Ubuntu Linux 测试技术
Linux系统之部署轻量级Markdown文本编辑器
【10月更文挑战第6天】Linux系统之部署轻量级Markdown文本编辑器
124 1
Linux系统之部署轻量级Markdown文本编辑器
|
2月前
|
Linux 开发工具 数据安全/隐私保护
linux异常一:feng 不在 sudoers 文件中,此事将被报告。yum提示Another app is currently holding the yum lock; waiting for
这篇文章介绍了在CentOS 7系统中安装Docker时遇到的两个常见问题及其解决方法:用户不在sudoers文件中导致权限不足,以及yum被锁定的问题。
46 2
linux异常一:feng 不在 sudoers 文件中,此事将被报告。yum提示Another app is currently holding the yum lock; waiting for
|
2月前
|
存储 运维 搜索推荐
|
1月前
|
存储 缓存 Linux
【Linux】另一种基于rpm安装yum的方式
通过本文的方法,您可以在离线环境中使用RPM包安装YUM并进行必要的配置。这种方法适用于无法直接访问互联网的服务器或需要严格控制软件源的环境。通过配置本地YUM仓库,确保了软件包的安装和更新可以顺利进行。希望本文能够为您在特定环境中部署YUM提供实用的指导。
164 0
|
2月前
|
Unix Linux 开发工具
Linux Vim的 命令大全
Linux Vim的 命令大全
30 0
|
2月前
|
Unix Linux Go
Linux 使用Yum安装Go和配置环境
Linux 使用Yum安装Go和配置环境
|
1月前
|
Linux 网络安全 数据安全/隐私保护
Linux 超级强大的十六进制 dump 工具:XXD 命令,我教你应该如何使用!
在 Linux 系统中,xxd 命令是一个强大的十六进制 dump 工具,可以将文件或数据以十六进制和 ASCII 字符形式显示,帮助用户深入了解和分析数据。本文详细介绍了 xxd 命令的基本用法、高级功能及实际应用案例,包括查看文件内容、指定输出格式、写入文件、数据比较、数据提取、数据转换和数据加密解密等。通过掌握这些技巧,用户可以更高效地处理各种数据问题。
95 8
|
1月前
|
监控 Linux
如何检查 Linux 内存使用量是否耗尽?这 5 个命令堪称绝了!
本文介绍了在Linux系统中检查内存使用情况的5个常用命令:`free`、`top`、`vmstat`、`pidstat` 和 `/proc/meminfo` 文件,帮助用户准确监控内存状态,确保系统稳定运行。
266 6
|
1月前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
80 3
|
1月前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
72 2
下一篇
DataWorks