佛山网站建设公司-印象互动,厦门做网站培训,全栈网站开发,什么是平台内部营销文章目录 一、再来理解重定向1.1 输出重定向效果演示1.2 重定向的原理1.3 dup21.4 输入重定向效果演示1.5 输入重定向代码实现 二、再来理解标准输出和标准错误2.1 同时对标准输出和标准错误进行重定向2.2 将标准输出和标准错误重定向到同一个文件 三、再看一切皆文件四、结语 … 文章目录 一、再来理解重定向1.1 输出重定向效果演示1.2 重定向的原理1.3 dup21.4 输入重定向效果演示1.5 输入重定向代码实现 二、再来理解标准输出和标准错误2.1 同时对标准输出和标准错误进行重定向2.2 将标准输出和标准错误重定向到同一个文件 三、再看一切皆文件四、结语 一、再来理解重定向
1.1 输出重定向效果演示 分析ls 指令是显示当前目录下的文件本质就是将当前目录下所有的文件名以字符串的形式写入到显示器文件。采用输出重定向 将原本应该写入显示器文件的内容写入到了 log.txtx 文件中。
1.2 重定向的原理
在讲解重定向原理前我们需要明确文件描述符的分配规则即从0下标开始寻找最小的没有使用的数组位置它的下标就是新打开文件的文件描述符。这里没有使用的意思是该下标里面存的是 NULL即没有指向任何一个文件对象。下面通过一段代码来为大家展示重定向的原理。
// mytest.c
int main()
{close(1);int fd open(FILE_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0666);if(fd 0){perror(open);return errno;}const char* str Hello Linux!\n;int cnt 5;while(cnt--){write(1, str, strlen(str));}return 0;
}代码分析上面这段代码就完美的展示了重定向的原理。首先调用 close 系统调用将 1 号下标对应的文件关闭关闭的意思就是将 1 下标里的内容置为 NULL原本 1 下标里面存储的内容是显示器文件对象的地址也就是标准输出 stdout紧接着调用 open 打开了一个文件根据文件描述符的分配规则新打开的这个文件的文件描述符就是 1即文件描述符表file*的数组1 号下标里面存储的就是新打开的文件对象的地址。接下来调用 write 接口向 1 号文件描述符中进行写入本来 1 号文件描述符对应的是显示器文件原本向显示器文件中写入的内容此时就被写入到新打开的文件中没有向显示器文件中写入因此屏幕上就不会出现字符串至此整个重定向的过程就结束啦。 总结重定向的本质是对数组下标里面的内容进行修改。
1.3 dup2
上面介绍了重定向的原理下面介绍一下实现重定向的系统调用 dup2。
#include unistd.h
int dup2(int oldfd, int newfd);dup2 的具体实现并不是向上面代码中那样先将一个文件描述符关闭然后紧接着再打开一个文件。dup2 的使用方法是用户在调用 dup2 接口前正常打开一个文件不用将显示器文件关闭此时新打开文件的文件描述符就是 3。接下来调用 dup2 将新打开文件的文件描述符作为 oldfd将显示器文件的文件描述符也就是 1作为 newfd。我们知道文件描述符本质上就是数组下标dup2 函数中执行的工作就是将 oldfd 下标里存储的文件对象地址拷贝到 newfd 下标里面至此重定向工作就完成了。 小Tipsdup2 的函数形参有一个误导我们可能会觉得新打开文件的描述符是 newfd其实不然这里的 newfd 是将要被覆盖的文件描述符oldfd 是新打开文件的描述符。
int main()
{// close(1);int fd open(FILE_PATH, O_WRONLY | O_CREAT | O_TRUNC, 0666);if(fd 0){perror(open);return errno;}dup2(fd, 1);const char* str Hello Linux!\n;int cnt 5;while(cnt--){write(1, str, strlen(str));}return 0;
}代码分析上面就是输出重定向的实现原理追加重定向只需要把 O_TRUNC 替换成 O_APPEND。
1.4 输入重定向效果演示 分析cat 指令本来是从键盘文件中获取输入然后写入显示器文件中采用输入重定向 后是从 log.txt 文件中获取输入然后写入显示器文件中。
1.5 输入重定向代码实现
// 输入重定向
int main()
{int fd open(FILE_PATH, O_RDONLY);if(fd 0){perror(open);}dup2(fd, 0);char str[1024];ssize_t ret read(fd, str, sizeof(str) - 1);if(ret 0){str[ret] \0;printf(echo: %s, str);}return 0;
}小Tips进程历史打开的文件与进行的各种重定向关系都和未来进行的程序替换无关程序替换并不影响文件访问。进程打开文件和何种重定向工作本质上都是进程管理的模块而程序替换只会把用户空间的代码和数据完全被新程序替换不会影响到进程管理。
二、再来理解标准输出和标准错误
int main()
{fprintf(stdout, Standard output messages\n);fprintf(stdout, Standard output messages\n);fprintf(stdout, Standard output messages\n);fprintf(stderr, Standard error messages\n);fprintf(stderr, Standard error messages\n);fprintf(stderr, Standard error messages\n);return 0;
}代码分析 是输出重定向也就是对标准输出1号文件描述符进行重定向。标准错误对应的2号文件描述符并没有进行重定向因此标准错误消息仍然打印在了屏幕上。
2.1 同时对标准输出和标准错误进行重定向
./mytest 1output.txt 2error.txt小Tips这段代码就是将1号文件描述符对应的标准输出文件重定向到 output.txt 文件将2号文件描述符对应的标准错误文件重定向到 error.txt 文件。这样以来屏幕上就不会有任何输出。 2.2 将标准输出和标准错误重定向到同一个文件
./mytest 1all.txt 21小Tips将标准输出和标准错误都重定向到 all.txt 文件中。
三、再看一切皆文件
所有操作计算机的动作都是通过进程去执行的所有的访问文件操作都是通过进程去实现的目前所有对文件的操作都依赖于进程。
小Tips所有的外设都被抽象成了文件每个外设都有自己的读写方法不同的外设读写方法一定是不同的。但是我们在对文件进行读写操作的时候始终调用的都是 read 和 write 方法这是因为操作系统为我们提供了一个方法集类型 file_operations该结构体里面都是函数指针类型指向外设的各种方法这就是多态的雏形。所谓的一切皆文件就是操作系统帮我们封装了一层文件对象进程对各种外设的操作全都变成了对文件的操作。
sszie_t read(int fd)
{task_struct-files-fd_array[fd]-f_op-read();
}四、结语
今天的分享到这里就结束啦如果觉得文章还不错的话可以三连支持一下春人的主页还有很多有趣的文章欢迎小伙伴们前去点评您的支持就是春人前进的动力