• Linux基础(yum,vim,gcc,gdb)


    Linux基本的命令我们会敲了,基本的文件概念以及权限概念我们也都了解了,接下来该学一些好用的工具,用Linux完成一些工作了

    目录

    yum 

    yum的作用

    yum基本操作

    vim

    vim的基本模式

    命令模式  

    插入模式

    底行模式

    可视化模式 

    gcc

    gcc基础命令

    动态链接和静态链接

    gdb

    什么是gdb

    gdb调试的相关指令 

                      命令

                      功能描述

    make和makefile

    为什么要用到make 和 makefile

    make 和 makefile 的使用 


    yum 

    yum的作用

    在windows系统中,若想要使用某种工具,是要到应用商店或者工具提供方的官方网址上去下载对应的软件安装包,手机上的操作也是如此,我们在手机上一般使用应用商店用的比较多。不知道大家好不好奇,软件一般由软件提供方放在自家服务器上,我们登录官方网址访问这个服务器就能够得到相应的软件安装包,这个过程我们需要访问软件提供方的服务器,而在应用商店中,我们并不需要去跳到某个网址上,而是点击下载就开始安装了,这是怎么做到的呢?

    还有就是应用商店一般都是手机生产商提供的,比如小米应用商店,华为应用商店,App store等等,你买哪家的手机,就会自动安装哪家的应用商店。

    应用商店简单来说起到了中间过渡的阶段,软件提供方会将自家软件下载地址提供给手机的应用商店,那么该应用商店会备注该软件名和下载地址,我们在应用商店上下载某个软件,只要搜索软件名,如果该软件已存在,点击下载,应用商店会自动帮我们完成软件的搜索和下载以及接下来的安装,这是一个自动化程度很高的过程,我们用的也很方便

    yum基本操作

    不过,这毕竟是windows和手机端,有着非常棒的图形化界面,将多种功能封装成一个软件,但是所占的空间很大,而Linux大多数情况下是不需要图形化界面的,所用工具的功能具有专一性,多是以命令的形式使用工具,那Linux该怎么下载安装工具呢?

    这就要用到yum命令,和手机端的应用商店类似,Linux提供了两种工具库,一种是安全,高效,受到官方肯定的官方工具库,另一种是安全性有待观察,不怎么常用的非官方工具库。 工具库存储着对应工具的下载地址,我们不需要指定要去哪个工具库,只要表明要下载的工具名就可,比如Linux有一个有趣的工具叫sl,输入这个命令就会出来一辆火车,刚开始我们是不能使用这个命令的,因为我们并没有下载这个工具

    输入命令 yum install sl  就可以下载这个工具玩玩了,这个命令要由root来执行,如果不是root用户,可使用sudo提权

    726265f5104741ed89cf9fce13c44a3a.png

    一般我们用到的工具大多都能在官方提供的库里找到,也可以直接输入指定的网址去下载相应的软件,至于要用到什么工具,则是根据自己的需求和经验而定的,所以大家可以经常逛逛相应的论坛,说不定就认识了一个你原先不知道的好用的软件

    如果你玩够了,不想要sl这个工具了,那该怎么删掉呢?

    输入命令 sudo yum remove sl

    fbd876cae742463ea46ed539a5deee46.png

     这里我就不卸载了

    vim

    vim的基本模式

    vim是一款非常强大的编辑软件,用的好,不仅不需要鼠标就能完成各种编辑操作,而且效率是相当的高,但是代价就是不好学。如果你用惯了鼠标加键盘的编辑操作,刚使用vim是很别扭的,觉得这种东西哪有鼠标来得快,实际上,vim用的好,比鼠标效率要高不少

    不同于windows中的记事本,打开之后就可以进行编辑操作,vim将编辑分为了不同的模式,各个模式有着不同的功能,我们可以简单的将vim分为五种模式,实际上是不止五种的,但是这五种比较常用,这里就只介绍这五种模式

    4f9fc88faf3545a3817fe0ce39304002.png

    命令模式  

    下图,我创建了一个名为 test 的文件 ,用vim进入后默认处于NORMAL模式,也就是命令模式,这个模式下,不能进行文本的编辑插入,我们可以在这个模式下浏览文章的内容,绿色闪动的是定位光标

    使用vim后我们就可以抛弃掉鼠标了,所以放弃使用鼠标的滚轮来查看内容,我们要习惯用键盘操作,那么在命令模式下怎么移动光标查看文章内容呢?

    h:     向右移动一个字符        w :  以单词为单位向右移动

    j :     移向下一行

    k:     移向上一行

    l :     向左移动一个字符         b :  以单词为单位向左移动

    4f12c1024b094f9c949d3e30ddacf24e.png

    复制粘贴及删除的操作也是在命令模式下完成的

    在命令模式下按下 yy 会复制光标所在行的整行内容,然后按下命令 p 则会在光标的下一行粘贴刚才已经复制的内容

    那要想复制多行的内容呢,在按下 yy 之前输入你想复制的行数,假如你输入了n行,那么就会复制光标所在行及其下面n-1行,共计n行内容,想粘贴几遍就在按下p之前输入粘贴的遍数

    上面说的是复制的操作,那如果是删除操作呢?

    在命令模式下按 dd 就可以删除光标所在行的整行内容,想删除多行,就在按下 dd 之前输入要删除的行数,假如你输入了n行,就会删除光标所在行及其下面n-1行,共计n行

    其实剪切和删除的操作是融在一起的,删除的内容会被放到寄存器里,在删除之后按下 p 就可以实现剪切的效果,当然不按 p 则是正常的删除操作,如果不想删掉整行内容,只想删几个字符,那么在命令模式下按 x/X 就可实现单个字符的删除

    vim是支持替换操作的,因此想替换某个单词就无需把这个单词给删掉从新写,在命令模式下输入R即可进入替换模式,从光标所在位置开始替换,如果只想替换一个字符,那在命令模式下按下 r 就可以完成一个字符的替换,不想替换了按ESC退出即可

    进行文本的操作,误操作是很正常的,如何撤销之前已经进行的操作呢?在命令模式下按下 u 就可以实现撤销操作,恢复操作之前的情况

    插入模式

    插入模式则是真正开始对文本进行操作,这个模式就是单纯的文本编辑,不想编辑了,按ESC退回到命令模式下即可,需要注意的是,只有命令模式和其他模式之间有通道,除了命令模式,其他任意模式之间都没有通道,也就是说只有在命令模式下才可以进入其他模式,例如不能从插入模式直接进入底行模式,要先退回到命令模式,再从命令模式下进入底行模式

    在命令模式下按 i / a / o 都可以进入插入模式

    按下 i  进入插入模式会在光标前面进行插入

    按下 a 进入插入模式会在光标后面进行插入

    按下 o 进入插入模式会在光标的下一行另起一行插入

    底行模式

    在命令模式下输入 ' : ' 即可进入底行模式,在底行模式下输入不同的命令可以进行不同的操作,比如搜索关键字,进行文章的保存,设置行号,进行文本的高亮显示,退出vim等等操作,都是在底行模式下进行的

    先说最基础的命令,进入底行模式后(下面命令默认大家已经输入了 :)

    q 是退出, w 是保存, !是强制执行,可以组合使用,q!强制退出,wq! 强制保存退出...

    set nu 是显示行号    set nonu 是取消行号显示   

    /关键字  是高亮显示所有关键字     noh   是取消高亮显示    n/N进行关键字间的切换

    可视化模式 

    大家在日常复制过程中,可能复制某文本的中间某一句的情况比较多,比如,我想复制第五行这段话中的网址然后访问,可是之前了解到的操作都是整行复制,或者单个字符的复制,这中间某句话该怎么复制呢?这个时候就用到了可视化模式 

    991628774d00470ba6ef784574018f4a.png  

    首先我们在命令模式下把光标定位到要复制的内容的首字符上,然后按下 ' v ' 进入可视化模式,然后接下来的操作就和在命令模式下的操作一样了,下面我演示一下 

    首先在命令模式下把光标定位到 w 处,然后右移(操作和命令模式下一样),黄色的即是被选中的内容,然后 y 复制一下,按下 y 之后会自动退到命令模式下,这样就完成了内容的复制

    1f6d3b5acbd049069cb8ce522a9b4486.png

    这是我完成复制之后在第六行复制的内容,这个过程若是用的熟练了,是比鼠标效率要高的

    683ace567af34871bd1ddd6cb1b51a66.png

    上面介绍的是vim的最基础的内容,相信大家把这些基础内容练熟了,编辑效率会得到很大的提高

    gcc

    gcc基础命令

    对于喜欢研究底层的同学来说,gcc是非常好用的编译器,因为gcc可以将代码编译到执行的每一个过程都展现出来,我们知道C/C++生成可执行文件要经过,预处理,编译,汇编,链接这四个阶段,这些内容是属于编译原理的,我们这里就只介绍输入什么命令可以在这几个阶段停下来

    在预处理阶段完成后停下来, gcc  -E  xxx.c  -o  test.i

    -E表示在预处理阶段停下来, -o表示生成一个临时文件储存预处理后的结果

    在编译阶段完成后停下来, gcc  -s  xxx.c  -o  test.s

    -s表示在编译阶段阶段停下来, -o表示生成一个临时文件储存编译处理后的结果

    在汇编阶段完成后停下来, gcc  -c  xxx.c  -o  test.o

    -s表示在汇编阶段阶段停下来, -o表示生成一个临时文件储存汇编处理后的结果

    因为链接阶段完成后,就直接生成了可执行文件,所以直接 gcc xxx.c 就可以

    动态链接和静态链接

    链接这个过程是相当的复杂,其中又分为动态链接和静态链接,我们这里只能简单的介绍一下,如果想详细的了解这个过程,可以阅读《程序员的自我修养》,这本书对链接这个过程讲解的很清晰到位,是本好书,有兴趣的可以看看,接下来简单的谈谈为什么要有链接这个阶段,以及静态链接和动态链接之间的区别

    首先谈谈为什么有链接这个过程,有些同学没有接触过项目文件的编写的,编写程序都是在一个单独的文件里进行,平时做做题,倒也没什么,但是在实现一个具体的项目时,是有很多的函数的,把所有函数的定义都和主函数写在一起,不仅难以阅读,更不易于日后代码的修改和维护

    所以,一般我们会创建一个新的文件专门存放各种函数的定义,假设在一个项目中,我们定义了两个源文件 A和B ,A用来存放主函数,里面是项目的测试逻辑,B文件存放各个函数的定义,就是各个逻辑块的具体实现,那这就有一个问题,放在两个文件里了,两个文件是单独编译的,A用到了B中定义的函数了,A怎么知道B中的内容呢?

    链接就是为了解决这个问题,简单来说链接就是在两个或多个文件之间建一座桥,如使上例中的A能够找到B中定义的内容

    事实上,只要我们引用了头文件,这个链接的过程就会发生,比如大家常用的 printf 和 scanf 函数,这两个函数并不是我们自己实现的,而是标准库给我们提供的,那么我们自己的程序用到 printf 时肯定要去找这个函数的定义,那这个函数的定义放在哪里呢? 大家可以理解成是放在官方的函数库里的 stdio.h这个文件里,这也是为什么我们要包含这个头文件的原因

    而链接的过程又分为了两种,分为动态链接和静态链接,也就是说去寻找 printf 函数定义的这个过程又分为了两种

    动态链接:假设我们程序中用到了 printf 函数,并且我们采用了动态链接的方式,那么程序在用到 printf 函数时会跑到动态库里寻找 printf 函数的定义,然后在动态库里执行完 printf 函数,再返回到原来的程序

    静态链接:同样假设我们程序中用到了 printf 函数,且采用了静态链接的方式,那么程序在用到 printf 函数时,会到静态库里找到 printf 函数的定义,然后把该定义拷贝一份到自己的源程序中,完成程序的执行

    可以简单的对比这两个过程,采用动态链接方式的可执行程序相比静态链接的大小是要小的,而越小就能越节省内存空间,这是动态链接的优势。动态链接运行中是受到动态库的影响的,如果动态库发生了较大的变化,势必会对采用动态链接的程序造成影响,而静态链接则是将需要的东西拷贝到自己的程序中,此后静态库再怎么变化,也影响不到自己的程序

    当然这些只是对动静态链接的简单认知,如果大家对这方面有兴趣可以阅读相关方面的书籍

    gdb

    什么是gdb

    前面说的是我们写好的程序,如何通过gcc来编译运行,接下来我们要了解程序出问题了如何进行调试

    程序的错误可以简单的分为两种,一种就是编译错误,一种是运行错误

    编译错误会在生成可执行程序之前报错,一般是语法错误导致的,比如不合规的语法使用,未定义的标识符,在链接时找不到相关的定义等等,编译错误的解决,我们要对语法知识足够熟悉,同时足够细心,仔细检查哪里犯错了

    运行错误是程序没有犯语法错误,通过了编译,形成了可执行文件,但是程序得到的结果与预期结果有偏差,一般是逻辑或者语义偏差等方面的问题,解决运行错误就要模拟在运行的环境下,手动一步或多步的执行代码,观察所求值的变化情况,从而定位到错误的地方

    而模拟运行环境,观察所求值的变化情况,我们就需要用到相关的调试工具,在Linux系统上,我们使用使用gdb来进行C/C++程序的调试

    注意:Linux 系统上默认生成的可执行文件是 release 版本,我们需要手动加上命令 -g 让其生成带有调试信息的 debug 版本,例如对一个编好的代码源文件  test.c 若要对其调试,先让它生成 debug 版本可执行文件,即 gcc -g test.c

    gdb调试的相关指令 

    生成 debug 版本的可执行文件之后,就可以启用gdb来进行程序的调试了,一般默认生成的可执行文件名叫 a.out  输入命令 gdb a.out (如果自己指定了可执行文件的名字,那就用自己

    指定的可执行文件的名字),到这就正式进入 gdb 开始调试,以下的步骤都是调试的命令

    命令

    功能描述

    list打印出要调试的代码信息,一次只打印10行,想接着打印,可以按回车键
    break(或b)  +   行号      在指定的一行设置一个断点
    r开始执行程序进行调试,直接运行到断点处(没有设置断点就无法执行程序,进行调试)
    info break(或b)查看已经设置的断点,每个断点都对应一个标号,标号从1开始
    delete breakpoints   + 标号删除对应标号的断点,如果不加标号,就是删除全部的断点
    next (或n)单步执行程序,也就是一步一步的执行程序
    step (或s)进入函数调用
    display  + 变量名跟踪查看一个变量,每次停下来都显示它的值

    undisplay

    取消对先前设置的那些变量的跟踪
    until  +  行号直接跳转到指定的行
    breaktrace(或bt)查看各级函数调用及参数

    这些是常用的调试指令,一般是够用了,剩下还有不少指令,感兴趣可以查阅看看

    make和makefile

    为什么要用到make 和 makefile

    如果你只用过vs编译器编写过工程项目文件,那么你可能没听说过make 和 makefile,vs 是集成开发环境,假如你用vs编写了一个工程项目文件,其中有两个源文件,一个头文件, 那么要编译运行这个工程文件,你只需要点击一下编译运行即可,但是在Linux环境下不行,因为有两个源文件,你需要同时编译这两个源文件,然后合并到一个可执行文件中

    如果需要多次编译这个工程文件,这样的操作是挺麻烦的,我们需要一个像 vs 那样自动化编译的工具, make 和 makefile 就是这样一个工具

    make 是一个命令, makefile 是一个文件,我们可以在 makefile 这个文件中设置自动化编译的过程,make则是执行设置好的自动化编译的指令,假设我们在 makefile 设置好了上述那个工程文件的自动化编译,那么想编译这个工程项目文件时,输入命令 make 即可

    make 和 makefile 的使用 

    如何配置 makefile 实现自动化编译呢?首先我们要 touch 一个Makefile, 名字叫 makefile 或是 Makefile都可

    以一个工程项目文件为例,这个工程包含 A.c ,  B.c  , C.h即两个源文件,一个头文件,

    若编译这个工程文件则要输入命令 gcc A.c B.c  -o test 生成一个可执行文件 test  

    a5fe1a9cdf7e48b2a7eebf0e2ef4bdbc.png

    d587af0655ec4d4d940e32e9b2075143.png  

    这样做,如果要多次编译,不仅操作不方便,看着也不舒服,那么我们用vim进入makefile配置自动化编译

    在配置之前,要知道 makefile 中有依赖关系的概念,什么意思呢?以上面的工程为例,要想生成可执行文件 test,则需要对 A.c B.c 进行编译合并,那么test就是依赖于 A.c 和 B.c

    配置makefile时首先要明确依赖对象,上面是test 依赖于 A.c B.c,书写时test: A.c B.c

    3bed0662349a4f0da2895b0ccfccda59.png

    换到下一行,然后按tab键,这个不可以省略,接着就是书写依赖对象之间的依赖关系

    因为test 是由 A.c B.c 编译得到的,所以依赖关系为 gcc A.c B.c  -o test

    2d09bef840ca4805a2e9a7f5de8aaca3.png

    这些步骤完成之后就可以进行自动化编译了 ,我们保存退出测试一下

    c7b8c93c7d344b14a6624caabe731456.png

    测试成功,这样以后再编译就不需要输入一大串命令,直接make一下就好,想改动就去Makefile 里更改,方便了很多呢,如果想要自动删除编译好的代码文件,可以尝试如下操作

     绿

    在绿色光标处填上你想要删除的文件,然后使用命令 make clean,就能够自动删除已填写的要删除的文件

  • 相关阅读:
    x86-7-页式管理(Paging)
    【面试题精讲】Java字符型常量和字符串常量的区别?
    数组的相关知识
    四边形不等式
    SpringBoot 20 Shiro授权的实现和整合Thymeleaf
    二叉树遍历——递归链式(C语言实现)
    【Python+Appium】自动化测试(十一)location与size获取元素坐标
    JS中的数据类型
    【洛谷 P5266】【深基17.例6】学籍管理 题解(映射+分支)
    堆排序,以及大顶堆构造过程Java实现
  • 原文地址:https://blog.csdn.net/m0_61350245/article/details/127399822