最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

Linux服务器开发-基础教程总结(1)-基础教程

互联网 admin 3浏览 0评论

Linux服务器开发-基础教程总结(1)-基础教程

目录

  • 前言
  • 正文
    • 1. 使用tar对文件进行压缩
    • 2. gcc的整个编译过程
    • 3. gcc的其他一些参数:
    • 4. lib静态库文件
    • 5. 共享库(动态库)
    • 6. GDB调试
    • 7. MakeFile
      • 基础知识
    • 8. C库函数
    • 9. 库函数与系统函数之间的关系
    • 10. open函数的使用
    • 11. read函数的使用
    • 12. readAndWrite函数的应用
    • 13.lseek
    • 14. stat函数
    • 15. access
    • 16. truncate
    • 17. link
    • 18. 常用命令
    • 19. dup,dup2(复制现有的文件描述符)
    • 20. fcntl
  • 总结
  • 参考

前言

本篇文章是观看视频所做的一些笔记。

正文

1. 使用tar对文件进行压缩

tar 参数: 不使用z/j 参数 命令只能对文件或目录打包

  1. c——创建——压缩
  2. x——释放——解压缩
  3. v——显示提示信息——压缩解压缩 可省略
  4. f——指定压缩文件的名字

z-——使用gzip的方式压缩文件 .gz
j——使用 bzip2的方式压缩文件 .bz2

压缩:
tar zcvf 生成的压缩包的名字(xxxx.tar.gz)
tar jcvf 生成的压缩包的名字(xxx.tar.bz2)

2. gcc的整个编译过程

预处理->编译->汇编->链接

编译期间是最耗时的。

  1. 这个编译过程很简单,我用罗列的方式应该就看起来简单很多了。
    首先,准备一个main.c ,我相信这个过程应该大家都是会的。然后正式开始编译:

gcc -E main.c -o main.i
gcc -S main.i -o main.s
gcc -c main.s -o main.o
gcc main.o -o main
最后直接执行这个./main即可。

看出来猫腻了吗,那个参数分别是E S c . -o 表示的是要生成的文件的名称,分别是i ,s ,o 。就这样记忆应该就可以记录下来了。

当然上面这个过程只是让你了解gcc编译的而整个过程,而实际上,你可以直接用一条指令就可以解决这样的问题了。

gcc main.c -o main

直接一条命令就可以将main.c 编译成功了。

3. gcc的其他一些参数:

-I : 指定头文件的路径
-D: 指定一个宏,相当于在文件中define 了一个宏。
-Wall :编译期间输出警告
-g:gdb调试时需要该参数
-L :后面接要依赖的库的目录
-l: 后面接具体依赖的库的名字,注意要去掉lib这个前缀。
-fPIC:就可以生成与位置无关的代码
-O(1-3):表示优化的级别 -O1 或-O2 或-O3

4. lib静态库文件

制作步骤:

  1. 生产对应的.o文件 —>c -o -c
  2. 将生成的.o文件打包 ar rcs+静态库的名字(libMytest.a)+生成的所有的.o

使用: main.c -L -l
gcc main.c -LlibPath -llibName -o app -Iinclude

发布 和使用静态库
3. 发布.a文件
4. 给.h文件

优点:
5. 由于静态库以及被打包到可执行文件中了,所以,在发布的时候就不用再发布静态库了。
6. 加载库的速度快。

缺点 :
7. 可执行文件中会变大。
8. 升级很麻烦,需要重新编译程序。

5. 共享库(动态库)

  1. 命令规则

lib +名字+ .so

  1. 制作步骤

生成与位置无关的代码(生成与位置无关的.o)
gcc -fPIC -c *.c -Iinclude
将.o打包成共享库

  1. 打包方式

gcc -shared -o lib名字.so *.o

  1. 使用方式

gcc main.c lib/libmy.so -o app
gcc main.c -LlibPath -lmytest -Iinclude -o app

  1. 查找依赖的库

ldd myApp
一般是先去查找环境变量

  1. 应用程序不能执行,动态连接器连接不到自己制作的库
  1. 临时设置的方法
    export LD_LIARARY_PATH = ./lib
  1. 永久设置的方法
  2. 找到动态链接库的配置文件:/etc/ld.so.conf
  3. 在该文件中添加动态库的目录(绝对路径)
  4. 更新 :sudo ldconfig -v

6. GDB调试

  1. 注意使用gcc编译程序的时候要使用-g的选项,才会是生成的可执行文件里面有行号,才可以进行操作。
  1. l :显示程序
  2. b num: 打断点
  3. i: info的意思
  4. i b: 代表显示出断点信息
  5. start :让程序启动,会开始跑到断点的那个地方
  6. n:next就是一步一步向后走,直接就执行完函数体了
  7. c: 就是continue 继续跑
  8. s: step进入到函数体的内部
  9. p: printf 表示的是打印某个变量
  10. ptype: 显示某个变量的类型
  11. start和run的区别:默认情况下,run 指令会一直执行程序,直到程序执行结束。如果程序中手动设置有断点,则 run 指令会执行程序至第一个断点处. start 指令会执行程序至 main() 主函数的起始位置,即在 main() 函数的第一行语句处停止执行(该行代码尚未执行)。
  12. file 文件名(绝对路径): 可以通过file命令指定要进行gdb调试的文件。
  13. –args: 指定需要传递给程序的数据
  14. set args: 可以借助 set args 命令指定目标调试程序启动所需要的数据
  15. run® 数据:可以使用run 或者start启动目标程序时,指定其所需要的数据。
  16. cd /tmp/demo :将 GDB 调试器的工作目录修改为 /tmp/demo
  17. path /temp/demo :某些场景中,目标调试程序的执行还需要临时修改 PATH 环境变量,此时就可以借助 path 指令
  18. run >a.txt: 通过run > 可以将运行的程序的输出结果输出到a.txt.
  19. watch cond: watch 称为监控断点,cond 表示要监控的变量
  20. catch event:建立捕捉断点的方式很简单
  21. catch 库的名称:监控库的加载(使用ldd App 可以获知其运行所需加载的动态库)
  22. break … if cond: 在某种条件下使断点发挥其作用。
  23. condition bnum expression:参数 bnum 用于代指目标断点的编号;参数 expression 表示为断点添加或修改的条件表达式。用于为 bnum 编号的断点添加或修改 expression 条件表达式
  24. condition bnum:用于删除 bnum 编号断点的条件表达式,使其变成普通的无条件断点
  25. ignore bnum count: 参数 bnum 为某个断点的编号;参数 count 用于指定该断点失效的次数。仅为一个整数,它用来表示该断点失效的次数
  26. next,step,until :都可以控制GDB调试器每次只执行一行代码。
  27. step next基本相同:但当step遇到函数时,会进入到函数内部,并在函数第一行代码处停下。
  28. until:不带参数的 until 命令,可以使 GDB 调试器快速运行完当前的循环体,并运行至循环体外停止。注意,until 命令并非任何情况下都会发挥这个作用,只有当执行至循环体尾部(最后一行代码)时,until 命令才会发生此作用。
  29. until location:location只是行号。
  30. finish:如果是在循环体内非最后一次循环,直接finish是出不来的。可以把循环的位置的断点去掉。就可以跳出函数体了。
  31. set var 变量名= 赋值:设置变量的值
  32. display 变量名:自动打印变量值,设置追踪变量
  33. undisplay:取消追踪变量
  34. info display:获取编号
  35. u: 跳出循环的命令
  36. quit:退出gdb

7. MakeFile

基础知识

  1. makefile中的shell的含义:

  2. 在规则中需要使用符号 本 身 的 地 方 , 需 要 书 写 两 个 连 续 的 本身的地方,需要书写两个连续的 本身的地方,需要书写两个连续的$

  3. $? 表示比目标还要新的依赖文件列表

  4. 分号是分隔符,反斜线是换行符,反斜杠是转义字符。

  5. CUR_C := $(filter %.c, ( C U R S R C ) ) : 过 滤 掉 所 有 (CUR_SRC)):过滤掉所有 (CURS​RC)):过滤掉所有(CUR_SRC)里面不符合%.c的文件 “filter”函数可以用来去除一个变量中的某些字符串.

  6. cat 111.txt | tr [a-z] [A-Z] > 222.txt:tr命令用于转换文本文件中的字符

  7. $(strip STRINT)
    函数名称:去空格函数—strip。
    函数功能:去掉字串(若干单词,使用若干空字符分割) “STRINT”开头和结尾的
    空字符,并将其中多个连续空字符合并为一个空字符。
    返回值:无前导和结尾空字符、使用单一空格分割的多单词字符串。
    函数说明:空字符包括空格、[Tab]等不可显示字符。

  8. $1表示取值

  9. $(foreach var text commond):
    var:局部变量
    text:文件列表,空格隔开,每一次取一个值赋值为变量var
    commond:对var变量进行操作(一般会使用var变量,不然没意义),每次操作结果都会以空格隔开,最后返回空格隔开的列表。

  10. call:call函数是唯一一个可以用来创建新的参数化的函数。 ( c a l l < e x p r e s s i o n > ; , < p a r m 1 > ; , < p a r m 2 > ; , < p a r m 3 > ; . . . ) 当 m a k e 执 行 这 个 函 数 时 , < e x p r e s s i o n > ; 参 数 中 的 变 量 , 如 (call <expression>;,<parm1>;,<parm2>;,<parm3>;...) 当make执行这个函数时,<expression>;参数中的变量,如 (call<expression>;,<parm1>;,<parm2>;,<parm3>;...)当make执行这个函数时,<expression>;参数中的变量,如(1), ( 2 ) , (2), (2),(3)等,会被参数< parm1>;,;,;依次取代。而;的返回值就是 call函数的返回值。

  11. =:代表的是赋值的意思:OBJECTS=$(SOURCES:.cpp=.o):代表的是将SOURCES 中的.o都代替成.cpp。

  12. wildcard取所有目录下的.c文件。

  13. 四种赋值方式
    简单赋值 ( := ) 编程语言中常规理解的赋值方式,只对当前语句的变量有效。
    递归赋值 ( = ) 赋值语句可能影响多个变量,所有目标变量相关的其他变量都受影响。
    条件赋值 ( ?= ) 如果变量未定义,则使用符号中的值定义变量。如果该变量已经赋值,则该赋值语句无效。
    追加赋值 ( += ) 原变量用空格隔开的方式追加一个新值。

  14. makefile 的编写
    规则的三要素:目标,依赖,命令
    目标:依赖条件
    命令
    一定要有个TAP键

  15. 在MakeFile中如果有多条规则的话,那么默认第一个目标就是终极目标。

  16. 为了防止每次修改一个就得 全部都编译,就把依赖的目标更改为.o文件。

  17. 工作原理:

    makefile版本

  18. 版本一:

app:main.c add.c sub.c mul.cgcc main.c add.c sub.c mul.c -o app
  1. 版本二:
  2. 版本三:使用变量名代表一系列名字 target:目标
    app: main.o add.o sub.o
    gcc main.o sub.o mul.o -o app
    %.o:%.c ->会在找main.o找不到的时候,自动把main填入达到%里面。
    makefile中的自动变量:

$<: 规则中的第一个依赖
$@:规则中的目标
$^:规则中的所有依赖
只能在规则的命令中使用。

  1. 版本四:
#makefile自己维护的变量
CC=cc
# CPPFLAGS:
CPPFLAGS = 
# 这里的cc其实就是gcc


5. 版本五:

  1. makefile给我们提供的函数都是返回值的。
  2. wildcard:获取指定目录下的.c文件:wildcard
  3. pastsubst:把指定目录下的.c 文件替换成.o。 这里模式匹配使用的是%,不是*。
  4. 给makefile提供函数传参,只需要将其参数与函数名用空格分离即可。但参数和参数之间使用逗号进行间隔。
  5. 取变量里面的内容记得要加$。
  6. 这样获取到的obj,就可以获取一系列函数的.o文件名字的集合。
  1. 版本六:Clean目标的加入


1.-rm :这个-的含义就是忽略掉当前命令执行失败的情况。
2. 查找指定目录下,指定类型的文件: src = $(wildcard ./*.c);
3. 匹配替换函数:obj = ( p a t s u b s t (patsubst %.c,%.o, (patsubst(src);
4. .PHONY:这个的意义是,这个是个伪目标,所以,即使当前文件夹中存在clean这个文件,也依然会执行clean下面的语句。

三个自动变量:

  1. $<: 规则中的第一个依赖
  2. $^:规则中的所有依赖
  3. $@:规则中的目标

8. C库函数

  1. 与位置无关的代码:

  1. #define NULL (void *)0 :这里的NULL其实就在受保护的地址
  2. 为什么要弄一个虚拟地址空间:
  3. 虚拟地址空间,注意虚拟的含义。

9. 库函数与系统函数之间的关系

  1. FD:文件描述符 FD_POS:文件指针 BUFFER:buffer
    2.write:做一个将用户空间拷贝到内核空间

10. open函数的使用

  1. 举个例子

11. read函数的使用

返回值:

  1. -1 :读取失败
  2. 0:文件读完了。
  3. 正数:文件读取上来的字节数。

12. readAndWrite函数的应用

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{//打开一个已经存在的文件int fd = open("file.txt",O_RDONLY);if(fd==-1){perror("open");exit(1);}//创建一个新文件---写操作int fd1 = open("newfile",O_CREAT|O_WRONLY,0664);if(fd1==-1){perror("open1");exit(1);}//read filechar buf[2048]={0};int count = read(fd,buf,sizeof(buf));if(count==-1){perror("read");exit(1);}while(count){//将读出的数据写入到另一个文件中国int ret =write(fd1,buf,count);printf("write bytes %d\n",ret);count = read(fd,buf,sizeof(buf));}//close fileclose(fd);close(fd1);return 0;
}

作用:将某个文件中的内容读取到另一个文件中的内容,新创建的一个文件。

13.lseek

  1. 获取文件大小
  2. 移动文件指针
  3. 文件拓展

应用

#include <stdlib.h>int main()
{int fd = open("aa",O_RDWR);if(fd==-1){perror("open file");exit(1);}int ret  = lseek(fd,0,SEEK_END);printf("file length=%d\n",ret);//文件拓展ret = lseek(fd,2000,SEEK_END);printf("return value:%d\n",ret);//实现文件拓展,需要再最后做一次写操作write(fd,"a",1);close(fd);return 0;
}
  1. 注意,在使用lseek进行拓展后,一定要额外进行一次拓展。不然,是没办法完成拓展操作的。

14. stat函数

依赖的头文件




这个的含义就是追踪和不追踪的意思。意思就是在遇到软链接的时候,是否会追踪到最底下的文件进行硕源。
stat是一个穿透的函数。

  1. 带l的是不穿透的。

15. access

成功就是0,不成功就返回-1。

16. truncate

17. link


unlink的应用

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{int fd = open("tempfile",O_CREAT|O_RDWR,0664);if(fd==-1){perror("open");exit(1);}//删除临时文件fileint ret = unlink("tempfile");//write filewrite(fd,"hello\n",6);//重置文件指针lseek(fd,0,SEEK_SET);//read filechar buf[24] = {0};int len =       read(fd,buf,sizeof(buf));//将读出的内容,写到屏幕上write(1,buf,len);//close fileclose(fd);return 0;
}

18. 常用命令

rename
int rename(const char*oldpath,const char* newpath);

chdir
改变进程的路径
getcwd
获取当前进程目录

rmdir
删除空目录
opendir
打开一个目录


readdir

应用

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>int getFileNum(char* root)
{//open dirDIR* dir = NULL;dir = opendir(root);if(dir==NULL){perror("opendir");exit(1);}//遍历当前打开的目录struct dirent* ptr = NULL;char path[1024];while(ptr=readdir(dir)!=NULL){//过滤,和if((strcmp(ptr->d_name,".")==0)||(strcmp(ptr->d_name,".."==0)){continue;}if(ptr->d_type==DT_DIR){//递归 读目录sprintf(path,"%s/%s",root,ptr->d_name);total += getFileNum(path);}//如果是普通文件if(ptr->d_type==DT_REG){total++;}}closedir(dir);//一定要关掉目录return total;
}int main(int argc,char * argv[])
{if(argc<2){printf("./a.out dir\n");}int total = getFileNum(argv[1]);printf("-->z %s has file numbers%d\n",argv[1],total);return 0;
}

19. dup,dup2(复制现有的文件描述符)


dup返回的就是文件描述符中没有被占用的最小的文件描述符。

20. fcntl

改变已经打开的文件的属性

总结

这个Linux服务器开发-基础教程总结(1) 视频到这就结束了,基本上把一些Linux开发的一些基本技能都展示了一下,师傅领进门修行在个人。接下来,就得靠自己去不断的熟练这些东西。接下来,开始看(2)的,就开始接触进程的一些概念了。

参考

  1. C/C++高级编程系列(1)之Linux服务器开发一基础教程

Linux服务器开发-基础教程总结(1)-基础教程

目录

  • 前言
  • 正文
    • 1. 使用tar对文件进行压缩
    • 2. gcc的整个编译过程
    • 3. gcc的其他一些参数:
    • 4. lib静态库文件
    • 5. 共享库(动态库)
    • 6. GDB调试
    • 7. MakeFile
      • 基础知识
    • 8. C库函数
    • 9. 库函数与系统函数之间的关系
    • 10. open函数的使用
    • 11. read函数的使用
    • 12. readAndWrite函数的应用
    • 13.lseek
    • 14. stat函数
    • 15. access
    • 16. truncate
    • 17. link
    • 18. 常用命令
    • 19. dup,dup2(复制现有的文件描述符)
    • 20. fcntl
  • 总结
  • 参考

前言

本篇文章是观看视频所做的一些笔记。

正文

1. 使用tar对文件进行压缩

tar 参数: 不使用z/j 参数 命令只能对文件或目录打包

  1. c——创建——压缩
  2. x——释放——解压缩
  3. v——显示提示信息——压缩解压缩 可省略
  4. f——指定压缩文件的名字

z-——使用gzip的方式压缩文件 .gz
j——使用 bzip2的方式压缩文件 .bz2

压缩:
tar zcvf 生成的压缩包的名字(xxxx.tar.gz)
tar jcvf 生成的压缩包的名字(xxx.tar.bz2)

2. gcc的整个编译过程

预处理->编译->汇编->链接

编译期间是最耗时的。

  1. 这个编译过程很简单,我用罗列的方式应该就看起来简单很多了。
    首先,准备一个main.c ,我相信这个过程应该大家都是会的。然后正式开始编译:

gcc -E main.c -o main.i
gcc -S main.i -o main.s
gcc -c main.s -o main.o
gcc main.o -o main
最后直接执行这个./main即可。

看出来猫腻了吗,那个参数分别是E S c . -o 表示的是要生成的文件的名称,分别是i ,s ,o 。就这样记忆应该就可以记录下来了。

当然上面这个过程只是让你了解gcc编译的而整个过程,而实际上,你可以直接用一条指令就可以解决这样的问题了。

gcc main.c -o main

直接一条命令就可以将main.c 编译成功了。

3. gcc的其他一些参数:

-I : 指定头文件的路径
-D: 指定一个宏,相当于在文件中define 了一个宏。
-Wall :编译期间输出警告
-g:gdb调试时需要该参数
-L :后面接要依赖的库的目录
-l: 后面接具体依赖的库的名字,注意要去掉lib这个前缀。
-fPIC:就可以生成与位置无关的代码
-O(1-3):表示优化的级别 -O1 或-O2 或-O3

4. lib静态库文件

制作步骤:

  1. 生产对应的.o文件 —>c -o -c
  2. 将生成的.o文件打包 ar rcs+静态库的名字(libMytest.a)+生成的所有的.o

使用: main.c -L -l
gcc main.c -LlibPath -llibName -o app -Iinclude

发布 和使用静态库
3. 发布.a文件
4. 给.h文件

优点:
5. 由于静态库以及被打包到可执行文件中了,所以,在发布的时候就不用再发布静态库了。
6. 加载库的速度快。

缺点 :
7. 可执行文件中会变大。
8. 升级很麻烦,需要重新编译程序。

5. 共享库(动态库)

  1. 命令规则

lib +名字+ .so

  1. 制作步骤

生成与位置无关的代码(生成与位置无关的.o)
gcc -fPIC -c *.c -Iinclude
将.o打包成共享库

  1. 打包方式

gcc -shared -o lib名字.so *.o

  1. 使用方式

gcc main.c lib/libmy.so -o app
gcc main.c -LlibPath -lmytest -Iinclude -o app

  1. 查找依赖的库

ldd myApp
一般是先去查找环境变量

  1. 应用程序不能执行,动态连接器连接不到自己制作的库
  1. 临时设置的方法
    export LD_LIARARY_PATH = ./lib
  1. 永久设置的方法
  2. 找到动态链接库的配置文件:/etc/ld.so.conf
  3. 在该文件中添加动态库的目录(绝对路径)
  4. 更新 :sudo ldconfig -v

6. GDB调试

  1. 注意使用gcc编译程序的时候要使用-g的选项,才会是生成的可执行文件里面有行号,才可以进行操作。
  1. l :显示程序
  2. b num: 打断点
  3. i: info的意思
  4. i b: 代表显示出断点信息
  5. start :让程序启动,会开始跑到断点的那个地方
  6. n:next就是一步一步向后走,直接就执行完函数体了
  7. c: 就是continue 继续跑
  8. s: step进入到函数体的内部
  9. p: printf 表示的是打印某个变量
  10. ptype: 显示某个变量的类型
  11. start和run的区别:默认情况下,run 指令会一直执行程序,直到程序执行结束。如果程序中手动设置有断点,则 run 指令会执行程序至第一个断点处. start 指令会执行程序至 main() 主函数的起始位置,即在 main() 函数的第一行语句处停止执行(该行代码尚未执行)。
  12. file 文件名(绝对路径): 可以通过file命令指定要进行gdb调试的文件。
  13. –args: 指定需要传递给程序的数据
  14. set args: 可以借助 set args 命令指定目标调试程序启动所需要的数据
  15. run® 数据:可以使用run 或者start启动目标程序时,指定其所需要的数据。
  16. cd /tmp/demo :将 GDB 调试器的工作目录修改为 /tmp/demo
  17. path /temp/demo :某些场景中,目标调试程序的执行还需要临时修改 PATH 环境变量,此时就可以借助 path 指令
  18. run >a.txt: 通过run > 可以将运行的程序的输出结果输出到a.txt.
  19. watch cond: watch 称为监控断点,cond 表示要监控的变量
  20. catch event:建立捕捉断点的方式很简单
  21. catch 库的名称:监控库的加载(使用ldd App 可以获知其运行所需加载的动态库)
  22. break … if cond: 在某种条件下使断点发挥其作用。
  23. condition bnum expression:参数 bnum 用于代指目标断点的编号;参数 expression 表示为断点添加或修改的条件表达式。用于为 bnum 编号的断点添加或修改 expression 条件表达式
  24. condition bnum:用于删除 bnum 编号断点的条件表达式,使其变成普通的无条件断点
  25. ignore bnum count: 参数 bnum 为某个断点的编号;参数 count 用于指定该断点失效的次数。仅为一个整数,它用来表示该断点失效的次数
  26. next,step,until :都可以控制GDB调试器每次只执行一行代码。
  27. step next基本相同:但当step遇到函数时,会进入到函数内部,并在函数第一行代码处停下。
  28. until:不带参数的 until 命令,可以使 GDB 调试器快速运行完当前的循环体,并运行至循环体外停止。注意,until 命令并非任何情况下都会发挥这个作用,只有当执行至循环体尾部(最后一行代码)时,until 命令才会发生此作用。
  29. until location:location只是行号。
  30. finish:如果是在循环体内非最后一次循环,直接finish是出不来的。可以把循环的位置的断点去掉。就可以跳出函数体了。
  31. set var 变量名= 赋值:设置变量的值
  32. display 变量名:自动打印变量值,设置追踪变量
  33. undisplay:取消追踪变量
  34. info display:获取编号
  35. u: 跳出循环的命令
  36. quit:退出gdb

7. MakeFile

基础知识

  1. makefile中的shell的含义:

  2. 在规则中需要使用符号 本 身 的 地 方 , 需 要 书 写 两 个 连 续 的 本身的地方,需要书写两个连续的 本身的地方,需要书写两个连续的$

  3. $? 表示比目标还要新的依赖文件列表

  4. 分号是分隔符,反斜线是换行符,反斜杠是转义字符。

  5. CUR_C := $(filter %.c, ( C U R S R C ) ) : 过 滤 掉 所 有 (CUR_SRC)):过滤掉所有 (CURS​RC)):过滤掉所有(CUR_SRC)里面不符合%.c的文件 “filter”函数可以用来去除一个变量中的某些字符串.

  6. cat 111.txt | tr [a-z] [A-Z] > 222.txt:tr命令用于转换文本文件中的字符

  7. $(strip STRINT)
    函数名称:去空格函数—strip。
    函数功能:去掉字串(若干单词,使用若干空字符分割) “STRINT”开头和结尾的
    空字符,并将其中多个连续空字符合并为一个空字符。
    返回值:无前导和结尾空字符、使用单一空格分割的多单词字符串。
    函数说明:空字符包括空格、[Tab]等不可显示字符。

  8. $1表示取值

  9. $(foreach var text commond):
    var:局部变量
    text:文件列表,空格隔开,每一次取一个值赋值为变量var
    commond:对var变量进行操作(一般会使用var变量,不然没意义),每次操作结果都会以空格隔开,最后返回空格隔开的列表。

  10. call:call函数是唯一一个可以用来创建新的参数化的函数。 ( c a l l < e x p r e s s i o n > ; , < p a r m 1 > ; , < p a r m 2 > ; , < p a r m 3 > ; . . . ) 当 m a k e 执 行 这 个 函 数 时 , < e x p r e s s i o n > ; 参 数 中 的 变 量 , 如 (call <expression>;,<parm1>;,<parm2>;,<parm3>;...) 当make执行这个函数时,<expression>;参数中的变量,如 (call<expression>;,<parm1>;,<parm2>;,<parm3>;...)当make执行这个函数时,<expression>;参数中的变量,如(1), ( 2 ) , (2), (2),(3)等,会被参数< parm1>;,;,;依次取代。而;的返回值就是 call函数的返回值。

  11. =:代表的是赋值的意思:OBJECTS=$(SOURCES:.cpp=.o):代表的是将SOURCES 中的.o都代替成.cpp。

  12. wildcard取所有目录下的.c文件。

  13. 四种赋值方式
    简单赋值 ( := ) 编程语言中常规理解的赋值方式,只对当前语句的变量有效。
    递归赋值 ( = ) 赋值语句可能影响多个变量,所有目标变量相关的其他变量都受影响。
    条件赋值 ( ?= ) 如果变量未定义,则使用符号中的值定义变量。如果该变量已经赋值,则该赋值语句无效。
    追加赋值 ( += ) 原变量用空格隔开的方式追加一个新值。

  14. makefile 的编写
    规则的三要素:目标,依赖,命令
    目标:依赖条件
    命令
    一定要有个TAP键

  15. 在MakeFile中如果有多条规则的话,那么默认第一个目标就是终极目标。

  16. 为了防止每次修改一个就得 全部都编译,就把依赖的目标更改为.o文件。

  17. 工作原理:

    makefile版本

  18. 版本一:

app:main.c add.c sub.c mul.cgcc main.c add.c sub.c mul.c -o app
  1. 版本二:
  2. 版本三:使用变量名代表一系列名字 target:目标
    app: main.o add.o sub.o
    gcc main.o sub.o mul.o -o app
    %.o:%.c ->会在找main.o找不到的时候,自动把main填入达到%里面。
    makefile中的自动变量:

$<: 规则中的第一个依赖
$@:规则中的目标
$^:规则中的所有依赖
只能在规则的命令中使用。

  1. 版本四:
#makefile自己维护的变量
CC=cc
# CPPFLAGS:
CPPFLAGS = 
# 这里的cc其实就是gcc


5. 版本五:

  1. makefile给我们提供的函数都是返回值的。
  2. wildcard:获取指定目录下的.c文件:wildcard
  3. pastsubst:把指定目录下的.c 文件替换成.o。 这里模式匹配使用的是%,不是*。
  4. 给makefile提供函数传参,只需要将其参数与函数名用空格分离即可。但参数和参数之间使用逗号进行间隔。
  5. 取变量里面的内容记得要加$。
  6. 这样获取到的obj,就可以获取一系列函数的.o文件名字的集合。
  1. 版本六:Clean目标的加入


1.-rm :这个-的含义就是忽略掉当前命令执行失败的情况。
2. 查找指定目录下,指定类型的文件: src = $(wildcard ./*.c);
3. 匹配替换函数:obj = ( p a t s u b s t (patsubst %.c,%.o, (patsubst(src);
4. .PHONY:这个的意义是,这个是个伪目标,所以,即使当前文件夹中存在clean这个文件,也依然会执行clean下面的语句。

三个自动变量:

  1. $<: 规则中的第一个依赖
  2. $^:规则中的所有依赖
  3. $@:规则中的目标

8. C库函数

  1. 与位置无关的代码:

  1. #define NULL (void *)0 :这里的NULL其实就在受保护的地址
  2. 为什么要弄一个虚拟地址空间:
  3. 虚拟地址空间,注意虚拟的含义。

9. 库函数与系统函数之间的关系

  1. FD:文件描述符 FD_POS:文件指针 BUFFER:buffer
    2.write:做一个将用户空间拷贝到内核空间

10. open函数的使用

  1. 举个例子

11. read函数的使用

返回值:

  1. -1 :读取失败
  2. 0:文件读完了。
  3. 正数:文件读取上来的字节数。

12. readAndWrite函数的应用

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main()
{//打开一个已经存在的文件int fd = open("file.txt",O_RDONLY);if(fd==-1){perror("open");exit(1);}//创建一个新文件---写操作int fd1 = open("newfile",O_CREAT|O_WRONLY,0664);if(fd1==-1){perror("open1");exit(1);}//read filechar buf[2048]={0};int count = read(fd,buf,sizeof(buf));if(count==-1){perror("read");exit(1);}while(count){//将读出的数据写入到另一个文件中国int ret =write(fd1,buf,count);printf("write bytes %d\n",ret);count = read(fd,buf,sizeof(buf));}//close fileclose(fd);close(fd1);return 0;
}

作用:将某个文件中的内容读取到另一个文件中的内容,新创建的一个文件。

13.lseek

  1. 获取文件大小
  2. 移动文件指针
  3. 文件拓展

应用

#include <stdlib.h>int main()
{int fd = open("aa",O_RDWR);if(fd==-1){perror("open file");exit(1);}int ret  = lseek(fd,0,SEEK_END);printf("file length=%d\n",ret);//文件拓展ret = lseek(fd,2000,SEEK_END);printf("return value:%d\n",ret);//实现文件拓展,需要再最后做一次写操作write(fd,"a",1);close(fd);return 0;
}
  1. 注意,在使用lseek进行拓展后,一定要额外进行一次拓展。不然,是没办法完成拓展操作的。

14. stat函数

依赖的头文件




这个的含义就是追踪和不追踪的意思。意思就是在遇到软链接的时候,是否会追踪到最底下的文件进行硕源。
stat是一个穿透的函数。

  1. 带l的是不穿透的。

15. access

成功就是0,不成功就返回-1。

16. truncate

17. link


unlink的应用

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main()
{int fd = open("tempfile",O_CREAT|O_RDWR,0664);if(fd==-1){perror("open");exit(1);}//删除临时文件fileint ret = unlink("tempfile");//write filewrite(fd,"hello\n",6);//重置文件指针lseek(fd,0,SEEK_SET);//read filechar buf[24] = {0};int len =       read(fd,buf,sizeof(buf));//将读出的内容,写到屏幕上write(1,buf,len);//close fileclose(fd);return 0;
}

18. 常用命令

rename
int rename(const char*oldpath,const char* newpath);

chdir
改变进程的路径
getcwd
获取当前进程目录

rmdir
删除空目录
opendir
打开一个目录


readdir

应用

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <dirent.h>int getFileNum(char* root)
{//open dirDIR* dir = NULL;dir = opendir(root);if(dir==NULL){perror("opendir");exit(1);}//遍历当前打开的目录struct dirent* ptr = NULL;char path[1024];while(ptr=readdir(dir)!=NULL){//过滤,和if((strcmp(ptr->d_name,".")==0)||(strcmp(ptr->d_name,".."==0)){continue;}if(ptr->d_type==DT_DIR){//递归 读目录sprintf(path,"%s/%s",root,ptr->d_name);total += getFileNum(path);}//如果是普通文件if(ptr->d_type==DT_REG){total++;}}closedir(dir);//一定要关掉目录return total;
}int main(int argc,char * argv[])
{if(argc<2){printf("./a.out dir\n");}int total = getFileNum(argv[1]);printf("-->z %s has file numbers%d\n",argv[1],total);return 0;
}

19. dup,dup2(复制现有的文件描述符)


dup返回的就是文件描述符中没有被占用的最小的文件描述符。

20. fcntl

改变已经打开的文件的属性

总结

这个Linux服务器开发-基础教程总结(1) 视频到这就结束了,基本上把一些Linux开发的一些基本技能都展示了一下,师傅领进门修行在个人。接下来,就得靠自己去不断的熟练这些东西。接下来,开始看(2)的,就开始接触进程的一些概念了。

参考

  1. C/C++高级编程系列(1)之Linux服务器开发一基础教程
发布评论

评论列表 (0)

  1. 暂无评论