Linux环境下常用工具
目录
一、软件包管理工具–yum
软件包:
Linux下安装软件, 一个通常的办法是下载程序的源代码, 并进行编译, 得到可执行程序,但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好,做成软件包(可以理解成windows上的安装程序)放在一个服务器上,通过包管理器可以很方便的获取到这个编译好的软件包,直接进行安装。
软件包和软件包管理器, 就好比,“App” 和 “应用商店” 这样的关系。yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器,主要应用在Fedora,RedHat,Centos等发行版上。
相关操作指令 | 含义 |
---|---|
yum list | 查看软件包 |
yum search keyword | 搜索软件包 |
yum install package | 安装软件包 |
yum remove package | 卸载软件包 |
(1)yum list罗列出当前一共有哪些软件包,内容很多,结合grep命令进行筛选。
rzsz工具:用于Windows机器与远程Linux机器传输文件。
//筛选出lrzsz软件包
yum list | grep lrzsz
//安装lrzsz软件包
sudo yum install lrzsz
//移除lrzsz软件包
sudo yum remove lrzsz
二、命令行编辑器–vim
1 操作模式
在Linux下vim中操作模式有很多,但常用的有三种。
- 普通模式:针对文本进行命令操作的模式,为其他模式切换的基础。
- 插入模式:文本编辑。
- 底行模式:进行文本文件的保存与退出。
2 模式切换
- 普通模式->插入模式:i、a、o、I、A、O 键。
- 任意模式->普通模式:ESC键。
- 普通模式->底行模式:英文
:
。
3 模式下的各种操作
(1)底行模式
操作 | 含义 |
---|---|
:w | 保存 |
:q | 退出 |
:wq | 保存并退出 |
:q! | 强制退出不保存 |
(2)普通模式
- 光标移动:
快捷键 | 表示含义 |
---|---|
h、j、k、l | 上、下、左、右 |
ctrl+f | 向上翻页 |
ctrl+b | 向下翻页 |
gg | 光标跳转到文件头 |
G | 光标跳转到文件尾 |
w | 以单词为单位向前移动 |
b | 以单词为单位向后移动 |
- 文本操作
快捷键 | 表示含义 |
---|---|
yy | 复制光标所在行 |
nyy | 从光标所在行开始复制n行 |
dd | 删除光标所在行 |
ndd | 从光标位置开始删除n行 |
dw | 删除单词 |
D | 删除本行光标以后的内容 |
ggdG | 清空文本内容 |
p | 向下将剪切板的内容粘贴1遍 |
np | 向下将剪切板的内容粘贴n遍 |
- 其他操作
快捷键 | 表示含义 |
---|---|
u | 撤销上一次操作 |
ctrl+r | 还原撤销 |
三、C/C++编译器–gcc/g++
1 编译
(1)编译器
我们平时写的代码实际上从执行到完成指定的功能,实际上就是编译器将代码程序编译成一个可执行的可执行程序。如用C语言写出来的代码实际上是一门高级语言,其本身并不可以被机器所直接识别。而编译器即是对代码进行编译,将代码解释成二进制机器指令。
而更早期的语言,如汇编指令,写出来的代码效率很高,但是其开发代码复杂,另外,由于指定的硬件只能用指定的指令来进行操作,故其跨平台移植性差。而编译器可以将相同的C语言程序代码,在不同的硬件平台上解释出不同的机器指令,这样在不同的平台下都可以得到运行。
不同语言有不同的编译器,C语言有gcc、clang、msvc等,C++有g++、c++lang等。
Linux下C和C++的编译器分别是gcc和g++。
(2)编译过程:预处理、编译、汇编、链接。
gcc常见操作选项:-E
、-S
、-c
、-o
。
操作选项 | 含义 |
---|---|
-E | 对文件进行预处理,将输入的.c 文件编译为.i 文件 |
-S | 将文件编译到汇编语言,将输入的.c 文件编译为.s 文件 |
-c | 只链接不链接为可执行程序文件,编译器将输入的.c 文件编译为.o 文件 |
-o | 文件输出到文件 |
-g | 添加调试信息,生成调试信息 |
格式:
gcc [选项] 要编译的文件 [选型] 目标文件
- 预处理(进行宏替换):展开所有的头文件、替换程序中的宏、解析条件编译并添加到文件中。
//gcc编译器只对文件hello.c进行预处理,预处理后生成hello.i文件
gcc -E hello.c -o hello.i
- 编译(生成汇编代码):将经过预处理的代码编译成汇编代码。
//gcc编译器对预处理后的hello.i文件进行编译,最后生成hello.s文件
gcc -S hello.i -o hello.s
- 汇编(生成机器可识别代码):将汇编语言文件编译成二进制目标文件。
//gcc编译器对预处理和编译后的hello.s文件进行汇编,最后生成hello.o文件
gcc -c hello.s -o hello.o
- 链接(生成可执行文件或库文件):将汇编出来的多个二进制目标文件链接到一起,形成最终的可执行文件,链接时可能还会涉及到静态库和动态库的问题。
//将汇编后的文件进行链接最终生成可执行程序文件hello
gcc hello.o -o hello
2 函数库
(1)函数库
如,在C语言程序中的printf
打印,在程序中我们并没有自己定义该函数的实现,而在预编译阶段中包含的stdio.h
头文件中也只是有该函数的声明。那该函数是从哪儿来的呢?
实际上,系统将printf这类的函数实现都实现在了名为libc.so.6
的库文件中去了,在没有特别的指定时,gcc编译器会到系统默认的搜索路径/usr/lib
下进行查找,即链接到libc.so.6
库中去,如此就可实现printf函数。这也是链接的作用所在。
(2)分类
- 静态库:
编译链接时,将库文件的代码全部加入到可执行文件中,其生成文件较大,但运行时候也不再需要库文件,后缀名一般为.a
。- 动态库:在程序运行时由运行时链接文件加载库,以便节省系统的开销,后缀名一般为
.so
。
3 链接
即将所有的源码指令以及库文件中的指令进行打包进行打包合并在一起。
- 动态链接:
链接动态库。将库中的函数符号信息表记录到可执行文件中,生成的可执行程序较小,内存中冗余代码较少,但是会产生运行时依赖(将库删除后会影响程序的执行)。- 静态链接:
链接静态库。将库中使用到的函数实现直接写入到可执行程序中,生成的可执行程序较大,内存中有可能会存在冗余代码,但是不会产生运行依赖(将库删除后并不影响程序的执行)。
gcc编译器默认链接方式为动态链接。
四、Linux调试器–gdb
调试器:调试一个程序的运行过程,查找程序中的问题所在。
1 调试版本
- debug版本:调试版本,不对代码进行任何优化,且加入调试信息。
- release版本:发布版本,会对代码进行一些优化,更利于程序的运行效率,无法调试。
故程序要被调试的前提是,该程序生成的是debug版本。而gcc编译器默认生成的是release版本,若要生成debug版本得在编译程序时加上-g
选项。
//生成调试版本的hello文件
gcc -g hello.c -o hello
2 调试过程
//hello.c文件
#include<stdio.h>
int main()
{
int a=0;
int b=10;
printf("hello world!\n");
printf("%d\n",a+b);
printf("%d\n",a-b);
return 0;
}
(1)gdb加载程序。
//gdb加载编译生成的debug版本main
gdb ./hello
(2)开始调试。
关键词 | 含义 |
---|---|
start | 开始对程序进行逐步调试 |
run | 直接运行程序 |
(3)逐行调试
关键词 | 含义 |
---|---|
next | 一行一行的运行程序,同vs下的逐过程调试 |
step | 同vs下的逐语句调试 |
until | 直接运行到指定文件的指定行 |
//直接运行到main.c文件的第4行
until hello.c:4
(4)查看代码
关键词 | 含义 |
---|---|
list | 默认查看调试运行附近的代码 |
//查看main.c文件的18行附近的代码。
list main.c:18
(5)断点操作
设置断点,使程序运行到断点位置就会停下,便于程序开发的调试。
操作 | 表示含义 |
---|---|
break hello.c:4 | 给指定文件的指定行设置断点 |
info break | 查看所有断点信息 |
continue | 从当前调试位置,即断点位置开始继续往下运行 |
delete n | 将指定n号断点进行删除 |
break function | 给function函数设置断点 |
(gdb) break hello.c:4
Breakpoint 1 at 0x40054f: file hello.c, line 4.
(gdb) break hello.c:6
Breakpoint 2 at 0x40055d: file hello.c, line 6.
(gdb) break hello.c:8
Breakpoint 3 at 0x400565: file hello.c, line 8.
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040054f in main at hello.c:4
2 breakpoint keep y 0x000000000040055d in main at hello.c:6
3 breakpoint keep y 0x0000000000400565 in main at hello.c:8
(gdb) delete 1
(gdb) info break
Num Type Disp Enb Address What
2 breakpoint keep y 0x000000000040055d in main at hello.c:6
3 breakpoint keep y 0x0000000000400565 in main at hello.c:8
(gdb)
(6)内存操作
①查看或设置变量的值。
使用关键字print
在调试过程中打印或设置各类变量的值。
//1. 查看变量a的值
print a;
//2. 设置变量a的值
print a=10;
//3. 查看指针ptr的内容
print ptr;
//4. 查看指针指向的内容
print *ptr;
②查看函数调用栈。
关键字backtrace
查看函数调用栈。
bt
(backtrace缩写)查看函数调用栈,可以定位程序在哪个函数出错。在程序运行时,函数都是逐个进行压栈的,程序当前运行位置是调用栈的栈顶函数,而当程序崩溃时,则栈顶函数一定是出错的函数。
(7)退出调试。
关键字quit
退出程序的调试。
五、项目自动化构建工具–make/Makefile
- Makefile:普通的文本文件,此文件中记录项目的构建规则。
- make:实际上为一个程序,称为Makefile解释器,解释Makefile中项目构建规则并进行执行,完成项目的构建。
make是一条命令,Makefile是一个文件,两者搭配使用,完成项目的自动化构建。
1 Makefile文件编写
Makefile编写规则:
目标对象:依赖对象
[tab]规则指令
hello.c文件C程序:
//hello.c文件
#include<stdio.h>
int main()
{
printf("hello world!\n");
return 0;
}
hello.c文件生成可执行文件编写的Makefile文件:
hello:hello.o
gcc hello.o -o hello
hello.o:hello.s
gcc -c hello.s -o hello.o
hello.s:hello.i
gcc -S hello.i -o hello.s
hello.i:hello.c
gcc -E hello.c -o hello.i
clean:
rm -rf hello.i hello.s hello.o hello
依赖的方法就是从依赖对象到目标对象的生成过程的对应规则。
当然此过程也可以简化为:
gcc hello.c -o hello
或者
gcc $^ -o $@
自动化变量,
$^
$@
。
- (1)
$@
:目标文件的名称。- (2)
$^
:所有的依赖文件,以空格分开,不包含重复的依赖文件。
2 make执行
make解释规则:
make在当前执行make指令的目录下找到Makefile文件,然后在Makefile中查找生成规则。
- make查找第一个目标对象,将其作为终极目标对象。
- 检测依赖对象与目标对象之间的时间关系,判断目标对象是否需要重新生成;目标对象不存在则需生成,目标对象生成后依赖对象又进行了修改则需生成。
- 若目标对象需生成,但依赖对象不存在或需重新生成,则查找依赖对象的生成规则先进行生成。
- 若需生成则执行相应的规则指令。
- 根据依赖关系,make会一层一层的找文件的依赖关系,直达最终编译出第一个目标文件。
项目的清理:
很多时候,生成可执行程序的过程需要先生成其他很多的依赖文件,在使用完成后就得进行项目的清理工作。
使用make clean
来对项目进行清理。
clean:
rm -rf hello.i hello.s hello.o hello
指令实现:
make
指令执行Makefile文件中记录hello.c文件生成可执行文件hello的生成规则,然后make clean
进行项目的清理。
[dev@localhost ~]$ cd ./linux
[dev@localhost linux]$ ls
hello.c ipc makefile multi process pthread sig
[dev@localhost linux]$ make
gcc -E hello.c -o hello.i
gcc -S hello.i -o hello.s
gcc -c hello.s -o hello.o
gcc hello.o -o hello
[dev@localhost linux]$ ls
hello hello.c hello.i hello.o hello.s ipc makefile multi process pthread sig
[dev@localhost linux]$ ./hello
hello world!
[dev@localhost linux]$ make clean
rm -rf hello.i hello.s hello.o hello
[dev@localhost linux]$ ls
hello.c ipc makefile multi process pthread sig
[dev@localhost linux]$