Linux命令
配套视频https://www.bilibili.com/video/BV1dt411f7TZ?p=64
p64 - p86
Day4 笔记
gdb调试 前提条件 可执行文件必须包含调试信息 gcc -g
- 启动gdb gdb app start --只执行一步
- 查看代码 l select_sort.c: 20 则可以查看该文件第20行 (l=list)
l select_sort.c: 函数名字 则可以查看该函数 再l 继续输出后续10行内容 继续回车则可继续看 - 设置断点
设置当前文件断点:break 22 (行号)
设置指定文件断点:b 文件名:22
设置条件断点:b 15 if i == 15 (条件)
删除断点:del/d 断点编号 - 查看设置的断点 info/i b/break
- 开始执行gdb调试 run 直接跑完
执行一步操作 start
继续执行: n(next)
执行多步,直接停在断点处:c (continue) - 单步调试
进入函数体内部:s (step) l 查看函数代码
从函数体内部跳出 finish (去掉断点)
不进入函数体内部:next(不进入函数内部)
退出当前循环:u - 查看变量的值 p 变量名字
- 查看变量类型 ptype 变量类型
- 设置变量的值 set var i = 10
- 设置追踪变量 display i (变量名)
取消追踪变量 info display 获取编号 undisplay + 编号 - 退出gdb调试 quit
Makefile编写 项目源代码管理工具
-
makefile命名 Makefile/makefile
-
makefile的规则
vi makefile
规则三要素 目标 依赖 命令
目标:依赖条件 app:main.c add.c sub.c mul.c
命令==(必须有缩进)== gcc main.c add.c sib.c mul.c -o app
子目标和终极目标的关系 : 向下查找规则 子目标为终极目标的前提
更新目标的原则:(终极目标写在最上面) 必须终极目标生成时间为最新 所以会内部自动更新
app: main.o add.o sub.o mul.o gcc main.o add.o sub.o mul.o -o app main.o : main.c gcc -c main.c add.o : add.c gcc -c addc sub.o : sub.c gcc -c sub.c mul.o : mul.c gcc -c mul.c
可以优化为:(替换命令为 :3,4s/app/$(target))
%.o : %.c 自动匹配
obj = main.o add.o sub.o mul.o target = app app : $(obj) gcc $(obj) -o $(target) %.o : %.c gcc -c $< -o $@
-
makefile的两个函数 (有返回值)
wildcard 查找指定目录下的文件
pastsubst 匹配替换# obj = main.o add.o sub.o mul.o src = $(wildcard ./*.c) #查找指定目录的.c文件 obj = $(patsubst ./%.c, ./%.o, $(src)) #匹配替换 target = app app : $(obj) gcc $(obj) -o $(target) %.o : %.c gcc -c $< -o $@
-
makefile三个自动变量 前面加$
$<: 规则中的第一个依赖依赖
$@:规则中的目标
$^:规则中的所有依赖只能在规则中的命令使用
makefile 自己维护的变量 全部大写# obj = main.o add.o sub.o mul.o src = $(wildcard ./*.c) #查找指定目录的.c文件 obj $(patsubst ./%.c, ./%.o, $(src)) #匹配替换 target = app app : $(obj) gcc $(obj) -o $(target) %.o : %.c gcc -c $< -o $@ .PHONY: clean #不进行更新比较 clean: #伪目标 rm $(obj) $(target) -f #删除.o app 执行时输入make clean -f 强制执行
若命令前面加上- 则执行错误也忽略 直接执行下面的命令
系统的IO函数
file 查看文件类型 Linux下可执行文件为ELF
虚拟地址的使用原因和优点
open函数 系统函数
man 2 open 查询man2章节
打开方式
必选项:
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 可读写
可选项:
O_CREAT 创建不存在的文件 文件权限umask 掩码 给定权限&掩码(取反) = 实际权限
O_TRUNC
O_EXCL
O_APPEND
errno error number 全局变量 extern int errno
使用:
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
int main()
{
int fd; // 文件描述符
//打开已经存在的文件
fd = open("hello.c",O_RDWR);
if (fd == -1)
{
perror("open fail");
exit(1);
}
//创建新文件
fd = open("myhello",O_RDWR|O_CREAT|O_EXCL, 0777);
if (fd == -1)
{
perror("open fail");
exit(1);
}
//关闭文件
int ret = close(fd);
printf("ret = %d\n",ret); // ret = 0 说明关闭成功
if (ret == -1)
{
perror("close fail");
exit(1);
}
}
read函数
#include<unistd.h>
返回值
-1 读文件失败
0 文件已读完
>
0
>0
>0 表示文件读取字节
write函数
#include <unistd.h>
返回值 写入的字节数
-1 写入数据失败
lseek函数
#incude<sys/typrs.h>
#include<unistd.h>
功能:
- 获取文件大小
- 移动文件指针
- 文件扩展
#include<sys/types.h>
#include<unistd.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");
//文件拓展,只能往后不能往前
int ret = lseek(fd, 2000, SEEK_END);
printf("return value %d\n", ret);
// 实现文件拓展 需要再最后做一次
write(fd,"a",1);
close(fd);
return 0;
}
返回值
读写文件实例
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<fcntl.h>
#include<unistd.h>
int main()
{
//打开已经存在的文件
int fd = open("english.txt",O_RDONLY);
if (fd == -1)
{
perror("open fail ");
exit(1);
}
//创建一个新的文件 写入
int fd1 = open("newfile", O_CREAT | O_WRONLY, 0664);
if(fd1 == -1)
{
perror("write fail");
exit (1);
}
//读取文件
char buf[2048] = {0};// 每次读取两个byte
int count = read(fd, buf, sizeof (buf)); // 返回值
if (count == -1)
{
perror("read fail");
exit(1);
}
while(count > 0)
{
//将读出的数据写入另一个文件中
int ret = write(fd1, buf, count);
printf("write bytes %d\n", ret);
//继续读取文件
count = read(fd, buf , sizeof(buf));
}
//关闭文件
close(fd);
close(fd1);
}