Linux 工具

目录

yum

vim

命令模式

插入模式

底行模式

替换模式

视图模式

gcc

预处理

编译

汇编

链接(动静态库后待补充)

make/Makefile

进度条

缓冲区

回车换行

实现

git

gdb


yum

软件的安装

  1. 源代码安装,需要自己搭建环境,编译;缺少库,代码移植性问题,交叉编译时候编不过
  2. rmp包安装,编译打包好形成一个rmp,安装的本质就是把可执行程序拷贝到指定目录下
  3. yum一键式安装,根据对应的软件名,自动取软件源里搜索,搜索出来之后,自动下载对应的软件包,然后解压拷贝安装到系统,在下载软件包之前,yum会自动解析软件包的依赖关系,并下载所有需要的依赖包。

如何评价某个Linux发行版的

  • 社区的活跃,官方文档的全面,配套的软件,生态,库,是否完整;大公司也在用,问题容易复现,提供大片的开源软件
  • yum源 /etc/yum.repos.d
  • yum源更新就是把base仓库换换

vim

  • 是一款多模式的文本编辑器,通常内置在Linux大多数发行版中

命令模式

  • 其他模式的都得从命令模式切过去;回到命令模式Esc键

光标移动

  • gg光标定位到最开始,shift g(G)光标定位到最后一行,n  G光标定位到第n行(n gg 也可以)
  • ^光标定位到当前行开头,$光标定位到当前行末尾
  • h←   j↓   k↑  l→    Backspace←
  • w光标以单词单位向后移动到下一个单词开头上;e移动到该单词末尾上
  • b光标以单词单位向前移动到上一个单词开头上,支持跨行

文本编辑

  • yy复制当前行, n yy从当前行开始往下复制n行
  • (n) dd 剪切当前行,默认一行,有n,则剪切n行
  • (n) pp 粘贴到下一行,默认一次
  • u 撤回,向前撤回;ctrl r撤回撤回,向后撤回
  • ~切换大小写,光标自动后移,不支持跨行
  • r char替换光标所在的字符为char
  • n r char从当前位置开始连续替换n个char,切光标移动到最后一个字符上
  • x 删除当前光标所在字符,后面的文本前移,若后面的删完了,则光标会往前移,不支持跨行
  • n x 删除当前光往后n个字符,小于等于n就删完,删完光标左移一格
  • X 向前删,x常用所以X是向前删,x是向后删

插入模式

  • 由命令模式进入插入模式 即正常编辑,i:光标不动;a:光标向右移动一个字符
  • o:光标向下新起一行

底行模式

  • :冒号即可进入底行模式
  • w!:强制写入
  • q!:强制退出,一般q不了是没保存
  • set nu 调出行号,set nonu 去掉行号 nu可以写全成number
  • ! + 默认的shell命令, 别名如:ll会找不到
  • /str:向下搜索str
  • ?str:向下搜索str   和less一样用法

多文本编辑

  • vs filename 即可打开另一个文本
  • ctrl ww 切换窗口
  • 可以把一个文本文件里的内容复制给另一个
  • 光标在哪个文件,操作哪一个

替换模式

  • R进入替换模式,覆盖当前光标所在字符,光标自动后移,不支持跨行

视图模式

  • ctrl v进入视图模式
  • 注释操作:选定区域为:ctrl v那行,到按下大i(I)时的那行;之后//;最后Esc退回到命令模式,这里的//可以换成别的,可以理解为块文本区域内的添加
  • 取注释:就是删除,先选定区域;再d即可
  • 这个模式下也可以使用命令模式的下的选项,部分不同 空格在这是后移一格
  • 视图模式下不能用右边的箭头,不然会切换到命令模式
  • 在大I后就是插入模式了,试了下,如果不同行都输入,,,不要这么做

没有保存退出会遇到的问题

  • 这时会将缓冲区里的文件写到临时文件里,在这个~/.local/share/nvim/swap/目录下,将其删除;或者自己在那个界面d即可

  • 使用vim test.c来创建文件test.c,若没有保存(w),则不会创建
  • 如果编译的时候报错 后面加上"+n"即可在打开文件时光标定位到第n行

vim配置

  • vim在启动时候,会自动扫描当前家目录下的.vimrc文件,让其在选项内生效,vim的配置,起始就是向 .vimrc里添加配置选项

gcc

程序的翻译

  • 本质是将源文件翻译成二进制文件

预处理

  • 主要处理以#开头的指令
  • 将头文件展开:将头文件里的内容拷贝到源文件里;主要用于声明函数、变量、宏和数据类型,以便在多个源文件中共享和复用代码
  • 去注释
  • 条件编译:#if、#ifdef、#ifndef、#else、#elif、#endif
  • 宏替换:#define,#undef
  • gcc -E test.c -o test.i

  • 默认是将输出打印到显示器上
  • .i后缀的文件仍然是源代码

编译

  • 将源代码转换成汇编代码
  • gcc -S test.i -o test.s
  • 可以不指定,默认生成特定格式的文件.s

汇编

  • 将汇编代码转换成目标代码(存放在目标文件里)
  • gcc -c test.s -o test.o
  • 生成的.o文件并不能执行
  • 目标文件中有机器指令,有一部分机器指令还是不能执行,需要链接器在做最后一步处理

二进制文件包括

  • 机器码(机器指令)(CPU可直接执行的最低级的代码),
  • 符号表(源代码中定义的函数和变量的符号信息,符号表用于链接阶段,帮助链接器解析跨文件的函数和变量引用)

链接

  • 将多个目标文件和库文件链接在一起,生成可执行文件
  • 可执行程序=机器码 + 段(代码段,数据段)+ 符号表 + 重定位信息
  • 所谓开发环境的安装就是下载安装并拷贝(从下载路径到指定路径)头文件,库文件到开发环境的指定路径下,可以让编译器找到

make/Makefile

  • 来自动化编译过程的工具和文件(make同时也是一个命令,用于执行Makefile中定义的规则和命令)
  • 具有依赖性的推导能力(涉及多个可执行(进程间通信))
  • 命令行中使用make命令来使make工具扫描Makefile文件时会自顶向下扫描,
  • 解析所有的变量定义、规则和伪目标声明;即make 工具自顶向下扫描 Makefile 文件
  • 但如果你在命令行中没有指定目标文件,make会尝试构建第一个这个默认的目标文件
  • 当一个目标有多个命令时,make按顺序依次执行这些命令;多个命令的顺序非常重要

使用

 11 cc=gcc
 12 src=test.c
 13 target=mybin
 14 
 15 $(target):$(src)
 16     @$(cc) $^ -o $@                                                                                          
 17 .PHONY:clean          
 18 clean:                
 19     @rm -f $(target)
  • src=test.c:等号左边是变量,右边是值
  • $(target):$(src):冒号左右形成依赖关系;左边是目标文件或伪目标,右边是依赖文件列表
  • @:使用在命令(依赖方法)前;不打印命令本身
  • $^:表示所有的依赖文件
  • $@:目标文件

.PHONT

  • 声明伪目标;若多个命令,空格隔开
  • 可以放在任何地方,但是最好放在合理的地方
  • 确保这些命令在每次运行时都能正确执行
  • 伪目标是一些特殊的命令或任务,它们不是实际的文件,这些任务通常用于构建管理

问:伪目标:用于生成特定的命令,而不生成实际的文件,:可是.PHONY$(target)也可以啊

  • 答:何目标都可以被定义为伪目标但在实践中,伪目标通常用于执行特定的命令或任务,而不是生成实际的文件

关于更新

  • make和Makefile不让重新编译:源文件代码大,源文件未修改;提高编译效率;形成的可执行文件与源文件对比

时间

  • touch可以修改三个时间,-a是说是只修改atime,但是ctime也被修改了,我的机子里ctime比atime早些
  • mtime可以和ctime一致,atime就是不行
  • atime的更新本质就是访问磁盘,而Linux系统充满大量的访问磁盘的IO操作,变相的减半系统效率;所以新款的策略是间隔一定的时间或者次数更新(如cat命令)具体取决于内核版本

进度条

缓冲区

  • c/c++针对标准输出,提供默认的缓冲区,这里主要是输出缓冲区
  • 输入缓冲区:输入都是字符的形式,输入到内存中的输入缓冲区中,回车的时候,程序通过stdin通道向输入缓冲区里读取内容,最后再通过格式化的读取到内存里
  • 接口:fflush(FILE* stream) 强制刷新输出缓冲区
  • 之所以可以看见printf的内容是因为数据从缓冲区被刷新出来
  • \n:行刷新

回车换行

  • \r:回车;回到行的开头

实现

process.h

#pragma once
#include <stdio.h>    

#include <unistd.h>    
#include <string.h>    
void process_v1();//演示进度条    
void process_v2(double);
typedef void (*callback)(double);
void download(callback);

#define RATE_MAX 100    
#define STYLE '#'    
#define LENGTH 100    
#define TIME (1000*10)    
#define TOTAL  1024*1024*8    
#define DOWNLOADSIZE  1024*20

process.c

#define  _CRT_SECURE_NO_WARNINGS
#include "process.h"


const char* ROTATE = "/-|\\";
void process_v1()
{
    int rate = 0;
    char str[LENGTH] = { '\0' };
    memset(str, '\0', sizeof str);

    while (rate < RATE_MAX)
    {
        printf("[%-100s][%2d%%][%c]\r", str, rate * 100 / RATE_MAX, ROTATE[rate % 4]);
        fflush(stdout);
        usleep(TIME);
        str[rate++] = STYLE;
    }
    printf("\n");
}
void process_v2(double rate)
{
    static char str[LENGTH] = { '\0' };

    printf("[%-100s][%.1f%%][%c]\r", str, rate, ROTATE[(int)rate % 4]);
    fflush(stdout);
    str[(int)rate] = STYLE;
}
void download(callback cb)
{
    double cur = 0;
    while (cur < (double)(TOTAL))
    {
        cur += (int)(DOWNLOADSIZE);
        //usleep(TIME);//模拟下载需要的时间
        double rate = cur * 100/ (int)(TOTAL);
        cb(rate);
    }
    cb(RATE_MAX);//传进去的100比率
    printf("\n");
}

 main.c

#define  _CRT_SECURE_NO_WARNINGS
#include "process.h"    

int main()
{
    download(process_v2);
    return 0;
}

process_v1

  • 单纯的演示进度条

process_v2

  • 通过传进来的比率来显示进度条;比如说把有关已下载的大小相关的数据传进去,这样就可以映射到一个下标

  • vs下没有unistd.h这个头文件
  • download函数的while循环里都不需要强转,因为式子里先算的cur
  • 最后打印的printf("\n"); 这为了防止命令行提示符覆盖进度条
  • ★使用宏的时候一定要带上扩号,在开始写的时候就是因为没有带上括号导致的段错误(str数组下标越界)

★漏洞与缺陷

  • 程序有可能不能达到预期,即进度条无法显示,因为str[(int)rate] = STYLE;这样的赋值方式有问题,问题在DOWNLOADSIZE    过大的时候,会有下标不赋值;所以这里可以采用for循环
  • 发现最后一次会打印101个,这是因为cb(RATE_MAX);在while的最后一次,其实越界了,误区:-100只不过是给出100个位置,不代表不会打印多余100个的字符。解决方法:在前面加if (rate < RATE_MAX);就可以解决

★解决边界与越界问题 

  • for (size_t i = strlen(str); i < rate && i < LENGTH; i++)  str[i] = STYLE;
  • i = strlen(str):为了防止重复覆盖,提高效率的
  • i < rate:这就是终点的意思
  • i < RATE_MAX:这是为了防止越界的
  • 同样的process_v1也得改成这样,那么printf要移动到下面才行;最后的cb(RATE_MAX);也没用了

git

        是一个版本控制器,git即充当客户端,也充当服务器;是一个只会记录变化的软件;去中心化的分布式软件

        gitee/github:基于git软件搭建的网站---使得版本管理可视化

操作

  • git --vision:有无安装git;查看git的版本
  • git clone HTTPS:远端克隆到本地;开源之后不需要登陆
  • git add .:git会自动扫描当前工作区(目录)的所有文件(子目录)中已更改或新创建的文件添加到暂存区
  • git commit -m "...":必须带上日志★;从暂存区添加到本地Git仓库
  • git push:输入账号密码(Linux);将本地仓库推送至远端,使本地仓库和远端仓库一致
  • git log:查看日志
  • git pull:同步远端和本地;从远程仓库获取最新更改并将其合并到本地分支的命令
  • git status:用于查看当前工作目录和暂存区状态的命令;提供了关于哪些文件已被修改、哪些文件已被暂存(即将被提交),以及哪些文件未被跟踪的信息

.gitignore(配置文件):通过特定的文件后缀匹配文件,凡是被找到的文件都不被add到暂存区

gdb

  • 发布模式为debug才能被调试
  • 系统里默认有安装
  • gcc/g++默认的发布模式是release;-g选项为以debug模式编译程序
  • -g形成的可执行程序内部有debug信息
  • 在Linux中形成的可执行程序的格式为ELF格式
  • 程序调试的本质是gdb再追踪这个进程

  • 不同的内核对应的命令的选项不太一样;选项大概为:行号,文件名,函数名,编号

开启、退出操作

  • 自动记录上次执行的命令
  • gbd exe:启用gdb,exe为debug模式发布的可执行程序
  • quit:退出
  • r程序开始跑,第二次r就重新跑了,不能从一个断点跑到另一个断点
  • 进入之后要调试,就必须要启动,那就要r;先打断点再r(启动程序)

显示内容

  • l n1,n2:显示n1到n2行之间的内容
  • l test.c:10:文件名:行号(冒号连接)
  • l n(l func_name):我这是以他们为中心显示上下5行,有可能你是为开头显示

断点

  • b n:第n行打断点,可以指定函数名和文件名
  • info b:查看断点
  • b mybin:20
  • b main
  • b test.c:func:20
  • d 编号:删段断点,n为段点编号(Num:线性增长,在一个gdb调试周期内不重复)

断点属性

  • info b
  • disable 编号:禁用n号断点
  • enable 编号:开启n号断点

调试

  • n:逐过程(c++的话,比如说cout会进去;对比vs,gdb这样不合理)
  • s:逐语句
  • p 变量名:查看一次变量的值,不常显示
  • display 变量名:常显示变量的值
  • undisplay 编号:变量名冒号左边
  • until n:运行到第n行,前提是要先r
  • finish:运行完当前函数,然后跳转到调用这个函数的行
  • c:从一个断点到另一个断点
  • bt:用来查看调用堆栈
  • set var i = 66:用于动态调试代码,不常用;主要用于进入条件语句

  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值