许昌企业网站去哪开发,wordpress 登录保护,asp网站设为首页代码,网站建设费算办公费吗文章目录 前言一、重定向二、系统调用dup2三、重定向的使用四、一切皆文件 前言
Linux进程默认情况下会有3个缺省打开的文件描述符#xff0c;分别是标准输入0#xff0c; 标准输出1#xff0c; 标准错误2#xff0c; 0,1,2对应的物理设备一般是#xff1a;键盘#xff… 文章目录 前言一、重定向二、系统调用dup2三、重定向的使用四、一切皆文件 前言
Linux进程默认情况下会有3个缺省打开的文件描述符分别是标准输入0 标准输出1 标准错误2 0,1,2对应的物理设备一般是键盘显示器显示器 而现在知道文件描述符就是从0开始的小整数。当我们打开文件时操作系统在内存中要创建相应的数据结构来描述目标文件。于是就有了file结构体。表示一个已经打开的文件对象。而进程执行open系统调用所以必须让进程和文件关联起来。每个进程都有一个指针*files, 指向一张表files_struct,该表最重要的部分就是包涵一个指针数组每个元素都是一个指向打开文件的指针所以本质上文件描述符就是该数组的下标。所以只要拿着文件描述符就可以找到对应的文件
一、重定向
文件描述符的分配规则在files_struct数组当中找到当前没有被使用的 最小的一个下标作为新的文件描述符。 我们先来看这段代码 毫无疑问我们标准输入标准输出和标准错误占据了file数组012位置然后我们执行程序也是打印在显示器上面
接下来我们再对源代码进行一些更改 我们执行程序发现没在显示器上面打印信息而是在文件里面打印了 而且此时的文件描述符为1也验证了我们上面说的 在files_struct数组当中找到当前没有被使用的 最小的一个下标作为新的文件描述符。 原理我printf默认用标准输出来封装而我标准输出的文件描述符在数组中对应的是1我printf只管往1里面写入不关心你1里面到底是谁所以当我们关闭原来的文件描述符为1的标准输出我1位置就放入了myfile的文件指针所以会向myfile中写入
二、系统调用dup2 dup是duplicate的缩写具有重定向的功能不需要我们像上面那样复杂的先去关闭一个指定位置再打开一个新文件的操作之所以叫这个名字我们需要从原理层来看 我们新打开的文件操作系统创建fiile的结构体并且其文件描述符分配为3指针数组中下标1位置直接对我们数组中下标为3位置进行拷贝1位置最后也指向log.txt的文件结构体
printf是C库当中的IO函数一般往 stdout 中输出但是stdout底层访问文件的时候找的还是fd:1, 但此时fd:1下标所表示内容已经变成了myfile的地址不再是显示器文件的地址所以输出的任何消息都会往文件中写入进而完成输出重定向。
因为IO相关函数与系统调用接口对应并且库函数封装系统调用所以本质上访问文件都是通过fd访问的。所以C库当中的FILE结构体内部必定封装了fd。
三、重定向的使用 执行文件 我们会发现hello error没有写入log.txt中而是直接打印在了显示器上这是为什么呢 前面我们已经有过重定向的知识了这里应该不难理解
//本质是将log.txt重定向到1也就是标准输出流的位置
完整写法应该是这样的
./test 1 log.txt
因为文件描述符1被重定向所以我们朝stdout里写入的数据虽然
依旧会向1所指向的位置
去写入但因为我们的1位置已经被新文件重定向也就是1中存的是新文件的信息地址
所以写入的时候会写入新文件的位置这也就解释了为什么log中会被写入数据而我们stderror标准错误流对应的文件描述符2不受影响
所以我依旧向显示器打印
我们也可以选择重定向到标准错误对应的文件描述符中 我们也可以将重定向1输出到log.txt中剩余的内容再重定向到文件描述符为2的位置
还可以同时把这些内容输入到一个文件当中去
四、一切皆文件
即使是外设Linux中也会把他们看成文件当成文件来进行管理 完整图