linux第二部分-操作系统
本章节延续linux第一部分继续学习
并非仅学习操作系统,实际上学习的是linux的系统编程,之后学习的是各样式的系统调用
初步认识系统编程
如何学习系统编程
资料推荐:man手册
如何阅读man手册
通过man man命令可以查看如何使用man手册
库函数帮助手册
某些系统可能没有预装库函数,因此需要先安装
输入以下命令并成功安装
$sudo apt install manpages-posix-dev |
根据手册页编号我们可以查看对应命令或函数对应手册的描述
比如我们要查看的是库调用中的printf函数(注意手册页,3对应是库函数中的printf函数)
man 3 printf |
文件
狭义概念:存储在外部存储设备介质上的数据集合
广义概念:传输速度慢,容量大,可以持久存储
常见的文件类型 :普通文件,目录文件,软链接,字符设备文件(鼠标,键盘等),块设备文件,管道文件,socket(网络通信)
文件使用
当我们想要访问某个存储设备的文件,肯定不能直接访问,而是通过将文件放到内存,再让cpu从内存读入的方式进行,内存中有一块专门的区域和外部设备进行交换数据,称为文件缓冲区
fopen
fopen应当属于库函数,所以我们想要man时需要看的是3号手册
- 根据FILE *fopen一行可知,参数列表有两个const修饰的字符串,返回值为一个FILE *
- pathname表示路径,mode有r(只读打开),w(只写创建),rw(读写创建)
- 如果返回的是空指针则有可能发生错误,通过perror函数可以查看报错信息
准备部分-文件报错
我们在执行可执行文件时有时候会加上一个参数,此时我们通过main函数中的argc参数可以用于检查
|
但这样的话我们每次新建一个文件都需要这么长几行,影响代码可读性
我们可以通过某些操作将这一操作通过带参数的宏定义封装进.h文件(宏定义一般放到头文件中)
在/usr/include中创建一个.h文件 ,可以命名为usually.h,意味着用于我们以后可能经常使用
创建后并给他普通用户可写的权限
转到usually.h进行编辑
//#define ARGS_CHECK(argc,num){if(argc != num) {fprintf(stderr,"args error!\n");return -1;}}
//在vscode下选中代码并按快捷键crtl+k,crtl保持按住,然后crtl+f进行自动格式化返回到fopen.c中,头文件可改为<usually.h>(使用<>引用是因为我们将usually.h放进了include文件夹中,系统根据<>提示优先在/usr/include目录下寻找对应头文件)
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
return 0;
}
此时fopen.c就可以通过ARGS_CHECK代替刚才的操作
我们再加上检查fp是否是NULL的操作
|
- argv[1]代表第一个参数,也就是我们要打开的文件,并以只读的方式打开
- perror用于打印报错信息
- 注意的是一个文件通过fopen打开后一定要通过fclose关闭
通过makefile文件使用make命令创建fopen可执行程序
执行fopen,并添加任意一个参数(目录下没有的文件),检测perror函数是否正常工作
创建一个文件,检测fopen是否可以正常打开该文件
我们发现perror这一操作也可以放到.h文件当中
并且应用于fopen.c中
int main(int argc,char* argv[])
{
ARGS_CHECK(argc,2);
FILE* fp = fopen(argv[1],"r");
ERROR_CHECK(fp,NULL,"fopen");
fclose(fp);
return 0;
}
追加模式
fopen的一种mode模式
- “a” append 只写追加(默认从文件结尾写入)
- “a+” 读写追加
日志系统
一种不可修改旧文件,只允许新加记录的系统
我们可以通过fopen.c的代码模拟一个日志系统
|
通过make再次生成可执行文件后进行测试
发现test文件中多了一行how are you
再次执行发现确实是追加模式
- 如果我们切换成a+模式,即读写追加模式
进行读操作
|
正常打印出了how are you
如果我们再把原来的写操作加上就会发现
读入时从文件开始读入,写入时跳到文件末尾写入
此处不再演示
fseek,ftell
fseek相当于一种游标,改变_ptr的位置
ftell就是告诉你_ptr的位置
|
- fseek中的参数SEEK_SET通过man可知是start of file的意思
从结果可得出,即使进行了fseek,追加模式的写入依然会在文件末尾进行
改变文件权限
命令 chmod
查看命令都有哪些手册可以man -f 命令查看
可以看到chmod不只是shell命令也可以是系统调用函数
可以通过man查看他的库函数是sys/stat.h
在我们的usually.h头文件再添加此头文件
查看chmod使用
- 通过说明可以知道他是用来改变文件权限的
- 通过参数可知const char* pathname为文件路径,mode_t类型为unsigned int,简要来说只需9bit即可分别代表ugo的读写执行权限
- 返回值 0成功,-1失败,并可以通过perror查看报错信息
使用chmod函数
|
make后执行发现dir目录文件改为777
再次修改依然可行
getcwd
通过man查看说明
获取当前工作目录
参数解析
- 库函数为unistd.h
- 返回值为字符串,buf为传入的字符串参数,传参时长度信息会丢失,因此需要一个size
- 当buf不为空时返回值为buf
- 当返回NULL时报错,通过perror查看错误信息
getcwd使用
首先将头文件加入到usually.h头文件当中
代码
|
执行结果
如果传入的参数为NULL,实际上getcwd会自动申请堆空间,此时返回值同样会获得当前目录,但申请的堆空间可能没有释放需要自己进行释放掉
|
chdir
man手册查看说明
改变当前工作目录
参数解析
- 库函数unistd.h
- 传入参数为要转到哪个路径下
- 成功返回失败返回-1,通过perror查看报错信息
chdir使用
|
我们发现结果输出表示目录已经改变,但实际上我们用户所在的目录并没有改变
这是因为当前工作目录为进程的属性,可以把每一个程序当做一个进程
目前有一个写shell命令的进程,另一个是通过./chdir执行出来的一个进程,输出shell命令进程的孩子,孩子目录更改了,不影响当前的目录,只会影响自己和子进程