第三章_Linux环境基础开发工具使用

1.Linux 软件包管理器 yum

简单尝试在root用户下安装一个小程序

[root@VM-12-12-centos ~]# yum install sl      //按回车


Is this ok [y/d/N]: y                         //按回车

输入sl命令,屏幕上会出现一辆小火车 

第三章_Linux环境基础开发工具使用_第1张图片

2.yum list 命令

通过 yum list 命令可以罗列出当前一共有哪些软件包

-bash-4.2$ yum list
由于包的数目可能非常之多 , 这里我们需要使用 grep 命令只筛选出我们关注的包. 例如查找 lrzsz 安装包
-bash-4.2$ yum list | grep lrzsz
lrzsz.x86_64                             0.12.20-36.el7                @os  

发现确实有这个安装包,接下来安装这个安装包(注意要在root用户下安装)。

[root@VM-12-12-centos ~]#  yum install lrzsz
yum 会自动找到都有哪些软件包需要下载 , 这时候敲 " y " 确认安装 .
出现 "complete" 字样 , 说明安装完成。

再安装一个软件源

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
//回车


Is this ok [y/d/N]: y
//回车

Installed:
  epel-release.noarch 0:7-14                                                            

Complete!

3. 安装vim

输入

[root@VM-12-12-centos ~]# yum install -y vim

安装好后,输入vim命令查看安装的版本

[root@VM-12-12-centos ~]# vim

第三章_Linux环境基础开发工具使用_第2张图片

 按shift+:(冒号),再按q+enter键退出。

第三章_Linux环境基础开发工具使用_第3张图片

4.使用vim进行首次编辑

1.创建test01.c文件,2.使用vim编辑test01.c文件

-bash-4.2$ touch test01.c
-bash-4.2$ ls
test01.c
-bash-4.2$ vim test01.c

2.进入文件后,是默认的“命令模式”,按“i”进入“插入模式”便可以进行编辑

第三章_Linux环境基础开发工具使用_第4张图片

3.编辑结束后,按“esc”键回到“命令模式”,再按“shift+:(冒号)”进入“底行模式”,输入“wq”再按回车键进行保存并退出。

4.输入 “cat test01.c”查看编辑的内容

-bash-4.2$ cat test01.c
#include 

int main()
{
printf("hello world\n");
return 0;
}

5.三种模式之间的关系

第三章_Linux环境基础开发工具使用_第5张图片

5. 命令模式下的文本操作

1. yy+p为复制

#include 
  3 
  4 int main()
  5 {
  6   printf("hello world\n");
  7   printf("hello world\n");
  8   printf("hello world\n");
  9   printf("hello world\n");                                                                                     
 10  return  0;
 11 }

2. yy+5p为复制5次

 #include 
  3 
  4 int main()
  5 {
  6   printf("hello world\n");
  7   printf("hello world\n");
  8   printf("hello world\n");
  9   printf("hello world\n");
 10   printf("hello world\n");
 11   printf("hello world\n");
 12   printf("hello world\n");                                                                                     
 13   printf("hello world\n");
 14   printf("hello world\n");
 15   printf("hello world\n");
 16   printf("hello world\n");
 17  return  0;
 18 }

3.(5)dd为剪切

2 #include 
  3 
  4 int main()
  5 {
  6   printf("hello world\n");
  7   printf("hello world\n");
  8   printf("hello world\n");
  9   printf("hello world\n");                                                                                     
 10  return  0;               
 11 } 

4. shift+g光标定位到文本末尾

#include 
  3 
  4 int main()
  5 {
  6   printf("hello world\n");
  7   printf("hello world\n");
  8   printf("hello world\n");
  9   printf("hello world\n");
 10  return  0;               
 11 }                                  //光标停留在文本末尾

5. gg光标定位到文本开始

 #include                   //此时光标定位到文本开头    
  3 
  4 int main()
  5 {
  6   printf("hello world\n");
  7   printf("hello world\n");
  8   printf("hello world\n");
  9   printf("hello world\n");
 10  return  0;               
 11 }

6. 3+shift+g光标定位到第三行

 1 
  2 #include 
  3                                  //此时光标定位到第三行                                                                                                   
  4 int main()
  5 {
  6   printf("hello world\n");
  7   printf("hello world\n");
  8   printf("hello world\n");
  9   printf("hello world\n");
 10  return  0;               
 11 }

7. shift+4(即$号)/shift+6(即^号)光标移动到行尾或行首

8.w/b以单词为单位进行左右移动

9. h/j/k/l为左右下上

10. shift+~为大小写切换

 1 
    2 #include 
    3 
    4 int main()
    5 {
    6   PRINTF("HELLO WORLD\N");     //此行切换为大写                                                                               
    7   printf("hello world\n");
    8   printf("hello world\n");
    9   printf("hello world\n");
   10  return  0;             
   11 }

11.(5)+ r + x,将已有字符替换成字符x

 1 
    2 #include 
    3 
    4 int main()
    5 {
E>  6   xxxxxf("hello world\n");         //此行前几个字母被替换成字母x
    7   printf("hello world\n");
    8   printf("hello world\n");                                                                                   
    9   printf("hello world\n");
   10   printf("hello world\n");
   11   printf("hello world\n");
   12   printf("hello world\n");
   13   printf("hello world\n");
   14   printf("hello world\n");
   15   printf("hello world\n");
   16   printf("hello world\n");
   17   printf("hello world\n");
   18   printf("hello world\n");
   19   printf("hello world\n");
   20  return  0;
   21 }

12. (3)+x删除3个字符

    1 
    2 #include 
    3 
    4 int main()
    5 {
    6   printf("hello world\n");
E>  7  ntf("hello world\n");            //此行删掉3个字符                                                                                  
    8   printf("hello world\n");                             
    9   printf("hello world\n");
   10   printf("hello world\n");
   11   printf("hello world\n");
   12   printf("hello world\n");
   13   printf("hello world\n");
   14   printf("hello world\n");
   15   printf("hello world\n");
   16   printf("hello world\n");
   17  return  0;               
   18 } 

6.Linux编译器-gcc/g++使用

gcc是用来编译C代码的,g++是用来编译C++代码的,但g++也可以直接用来编译C代码。所以这里只展示一下g++的使用方法。

[root@VM-12-12-centos 2022_07_25]# touch test01.cpp    //创建cpp文件
[root@VM-12-12-centos 2022_07_25]# ls
test01.cpp
[root@VM-12-12-centos 2022_07_25]# vim test01.cpp      //编辑C++代码



  1 #include 
  2 #include 
  3 int main()
  4 {
  5   std::cout<<"hello world"<

1. 背景知识
1. 预处理(进行宏替换)
2. 编译(生成汇编)
3. 汇编(生成机器可识别代码)
4. 连接(生成可执行文件或库文件)
2. gcc 如何完成
格式 gcc [ 选项 ] 要编译的文件 [ 选项 ] [ 目标文件 ]
预处理 ( 进行宏替换 )
预处理功能主要包括宏定义,文件包含,条件编译,去注释等。
预处理指令是以#号开头的代码行。
实例: gcc –E hello.c –o hello.i
选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。
选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。
编译(生成汇编)
在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查
无误后,gcc 把代码翻译成汇编语言。
用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。
实例: gcc –S hello.i –o hello.s
汇编(生成机器可识别代码)
汇编阶段是把编译阶段生成的“.s”文件转成目标文件
读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了
实例: gcc –c hello.s –o hello.o
连接(生成可执行文件或库文件)
在成功编译之后,就进入了链接阶段。
实例: gcc hello.o –o hello
在这里涉及到一个重要的概念 : 函数库
我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实现“printf”函数的呢?
答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用
函数库一般分为静态库和动态库两种。
静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a”
动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc hello.o –o hello
gcc默认生成的二进制程序,是动态链接的,这点可以通过 file 命令验证。
gcc 选项
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S  编译到汇编语言不进行汇编和链接
-c  编译到目标代码
-o 文件输出到 文件
-static 此选项对生成的文件采用静态链接
-g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统有动态库.
-O0
-O1
-O2
-O3
编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w  不生成任何警告信息。
-Wall 生成所有警告信息。
gcc 选项记忆
esc,iso 例子

3.安装C、和C++静态库

yum install -y glibc-static           //安装C静态库
yum install -y libstdc++-static       //安装C++静态库    

使用静态库编译文件

[root@VM-12-12-centos 2022_07_25]# gcc test01.c -o test01_c -static
[root@VM-12-12-centos 2022_07_25]# ll
total 852
-rwxr-xr-x 1 root root 861288 Jul 25 11:15 test01_c
-rw-r--r-- 1 root root     74 Jul 25 11:01 test01.c
-rw-r--r-- 1 root root    130 Jul 25 10:27 test01.cpp
[root@VM-12-12-centos 2022_07_25]# ./test01_c
hello world


[root@VM-12-12-centos 2022_07_25]# g++ test01.cpp -o test01_cpp -static
[root@VM-12-12-centos 2022_07_25]# ll
total 2428
-rwxr-xr-x 1 root root  861288 Jul 25 11:15 test01_c
-rw-r--r-- 1 root root      74 Jul 25 11:01 test01.c
-rwxr-xr-x 1 root root 1612672 Jul 25 11:17 test01_cpp
-rw-r--r-- 1 root root     130 Jul 25 10:27 test01.cpp

7.Linux调试器-gdb使用

1. 背景
程序的发布方式有两种,debug模式和release模式
Linux gcc/g++出来的二进制程序,默认是release模式
要使用gdb调试,必须在源代码生成二进制程序的时候, 加上 -g 选项
2. 开始使用
(重点)
gdb binFile 退出: ctrl + d 或 quit 调试命令:
list/l 行号:显示binFile源代码,接着上次的位置往下列,每次列10行。
list/l 函数名:列出某个函数的源代码。
r或run:运行程序。
n 或 next:单条执行。
s或step:进入函数调用
break(b) 行号:在某一行设置断点
break 函数名:在某个函数开头设置断点
info break :查看断点信息。
fifinish:执行到当前函数返回
(了解)
print(p):打印表达式的值,通过表达式可以修改变量的值或者调用函数
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
3. 理解
和windows IDE对应例子

使用实例:

[root@VM-12-12-centos 2022_07_25]# ll                     //查看文件
total 4
-rw-r--r-- 1 root root 130 Jul 25 10:27 test01.cpp
[root@VM-12-12-centos 2022_07_25]# g++ test01.cpp -g      //以Debug模式编译cpp文件
[root@VM-12-12-centos 2022_07_25]# ll
total 24
-rwxr-xr-x 1 root root 20480 Jul 25 11:40 a.out           
-rw-r--r-- 1 root root   130 Jul 25 10:27 test01.cpp
[root@VM-12-12-centos 2022_07_25]# gdb a.out              //使用gdb进行调试
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later 
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
...
Reading symbols from /root/2022_07_25/a.out...done.
(gdb) l 0                                                 //输入 l 0从第1行开始显示10行
1	#include                                    //如果代码很多,按“回车”键继续显                                                      
2	#include                                     //示剩下的代码
3	int main()
4	{
5	  std::cout<<"hello world"<

8.Linux项目自动化构建工具-make/Makefifile

背景
会不会写makefifile,从一个侧面说明了一个人是否具备完成大型工程的能力
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefifile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作。makefifile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefifile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefifile都成为了一种在工程方面的编译方法。make是一条命令,makefifile是一个文件,两个搭配使用,完成项目自动化构建。
理解
依赖例子
实例代码
C代码
#include 
int main()
{
 printf("hello Makefile!\n");
 return 0;
}
Makefifile文件
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
.PHONY:clean
clean:
 rm -f hello.i hello.s hello.o hello

依赖关系
上面的文件 hello ,它依赖 hell.o
hello.o , 它依赖 hello.s
hello.s , 它依赖 hello.i
hello.i , 它依赖 hello.c
依赖方法
gcc hello.* -option hello.* ,就是与之对应的依赖关系
原理
make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么,
1. make会在当前目录下找名字叫“Makefifile”或“makefifile”的文件。
2. 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“hello”这个文件,
并把这个文件作为最终的目标文件。
3. 如果hello文件不存在,或是hello所依赖的后面的hello.o文件的文件修改时间要比hello这个文件新(可以用 touch 测试),那么,他就会执行后面所定义的命令来生成hello这个文件。
4. 如果hello所依赖的hello.o文件不存在,那么make会在当前文件中找目标为hello.o文件的依赖性,如果找到则再根据那一个规则生成hello.o文件。(这有点像一个堆栈的过程)
5. 当然,你的C文件和H文件是存在的啦,于是make会生成 hello.o 文件,然后再用 hello.o 文件声明make的终极任务,也就是执行文件hello了。
6. 这就是整个make的依赖性,make会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。
7. 在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,make根本不理。
8. make只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,我就不工作啦。
项目清理

工程是需要被清理的
#include
int main()
{
printf("hello Makefile!\n");
return 0;
}
.PHONY:clean
clean:
rm -f hello.i hello.s hello.o hello
像clean这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要make执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。但是一般我们这种clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。可以将我们的hello目标文件声明成伪目标,测试一下。

使用实例:

[root@VM-12-12-centos 2022_07_25]# touch test01.c
[root@VM-12-12-centos 2022_07_25]# ls
test01.c
[root@VM-12-12-centos 2022_07_25]# touch makefile
[root@VM-12-12-centos 2022_07_25]# ll
total 0
-rw-r--r-- 1 root root 0 Jul 25 12:19 makefile
-rw-r--r-- 1 root root 0 Jul 25 12:19 test01.c
[root@VM-12-12-centos 2022_07_25]# vim test01.c


  1 #include 
  2 int main()
  3 {
  4   printf("hello world\n");                                                                 
  5   return 0;
  6 }
  
[root@VM-12-12-centos 2022_07_25]# vim makefile

  1 test:test01.c                                   //添加依赖关系                                                                       
  2 (按一下tab键) gcc test01.c -o test               //添加依赖方法


[root@VM-12-12-centos 2022_07_25]# make             //输入make直接生成可执行文件
gcc test01.c -o test
[root@VM-12-12-centos 2022_07_25]# ll
total 20
-rw-r--r-- 1 root root   82 Jul 25 12:24 makefile
-rwxr-xr-x 1 root root 8360 Jul 25 12:26 test       //可执行文件
-rw-r--r-- 1 root root   78 Jul 25 12:26 test01.c
[root@VM-12-12-centos 2022_07_25]# ./test           //运行文件
hello world

使用make clean清除生成的文件

[root@VM-12-12-centos 2022_07_25]# ll
total 8
-rw-r--r-- 1 root root 99 Jul 25 12:45 makefile
-rw-r--r-- 1 root root 78 Jul 25 12:26 test01.c
[root@VM-12-12-centos 2022_07_25]# vim makefile


  1 test:test01.c
  2   gcc test01.c -o test 
  3 
  4 .PHONY:clean                                   //.PHONY为关键字,后面的clean为伪目标
  5 clean:                                         //.PHONY后面跟的伪目标一定会被执行
  6   rm -r test                                   //依赖方法


[root@VM-12-12-centos 2022_07_25]# make
gcc test01.c -o test 
[root@VM-12-12-centos 2022_07_25]# ll
total 20
-rw-r--r-- 1 root root   99 Jul 25 12:46 makefile
-rwxr-xr-x 1 root root 8360 Jul 25 12:46 test      //可执行文件
-rw-r--r-- 1 root root   78 Jul 25 12:26 test01.c
[root@VM-12-12-centos 2022_07_25]# ./test
hello world
[root@VM-12-12-centos 2022_07_25]# make clean      //清除可执行文件
rm -r test	
[root@VM-12-12-centos 2022_07_25]# ll
total 8
-rw-r--r-- 1 root root 99 Jul 25 12:46 makefile
-rw-r--r-- 1 root root 78 Jul 25 12:26 test01.c

9. Linux第一个小程序-进度条

9.1 \r&&\n

回车概念
换行概念
行缓冲概念
什么现象?
#include 
int main()
{
 printf("hello Makefile!\n");
 sleep(3);
 return 0;
}

打印出内容后,再停顿三秒。

什么现象?
#include 
int main()
{
 printf("hello Makefile!");
 sleep(3);
 return 0;
}

停顿三秒后再打印内容

什么现象?
#include 
int main()
{
 printf("hello Makefile!");
 fflush(stdout);              //立刻刷新显示器
 sleep(3);
 return 0;
}

打印出内容后,再停顿三秒。

9.2 进度条代码

#include 
#include 
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;
}
yum ins

输出结果

[###################################################] [100%] [|]

9.3 使用 git 命令行

在gitee注册账户后点击新建仓库

第三章_Linux环境基础开发工具使用_第6张图片

 

第三章_Linux环境基础开发工具使用_第7张图片

 第三章_Linux环境基础开发工具使用_第8张图片

 

输入 git clone + 地址

[root@VM-12-12-centos ~]# git clone https://gitee.com/cshappyheaven/linux--c--c.git

输入gitee的帐户和密码

看到已经添加成功

 进入仓库,创建一个.c文件

 

输入 git add +文件名

输入 git commit -m +"日志"

[root@VM-12-12-centos linux--c--c]# git add 01.c
[root@VM-12-12-centos linux--c--c]# git commit -m "第一个程序"

上面两个步骤是上传到本地仓库,最后上传到远地仓库

输入 git push

[root@VM-12-12-centos linux--c--c]# git push

输入 ls -al 查看该目录下所有文件

第三章_Linux环境基础开发工具使用_第9张图片

输入vim .gitignore 可以设置禁止上传的文件

第三章_Linux环境基础开发工具使用_第10张图片

 

 以上为git的基本用法。

你可能感兴趣的:(Linux编程,linux,运维,服务器)