[Chapter10] 对重定向的理解
Posted uestcliming666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Chapter10] 对重定向的理解相关的知识,希望对你有一定的参考价值。
常用的重定向如who->userlist.txt将who的输出定向到文件userlist.txt,这是如何做到的呢?
who的默认输出对象是标准IO中的stdout,文件描述符为1,而重定向所做的事情是将文件描述符1从默认的tty设备文件移开,而重新分配给其他文件,在本例中为userlist.txt,这样who在向文件描述符1输出用户清单时就会输出到userlist.txt中。
同理,对于输入数据的重定向sort<pricelist.txt来说,被重定向的就是sort的输入源,sort的默认输入源的文件描述符为0,sort从描述符为0的文件——tty输入读取数据,而重定向所做的就是将0从tty输入移开,而分配给pricelist.txt,这样sort就会从pricelist.txt文件中读取数据进行排序,然后输出。
重定向到文件的小结:
(1)标准输入、输出、错误分别对应于文件描述符0、1、2;
(2)内核总是使用最低可用文件描述符;
(3)文件描述符集合通过exec调用传递,且不会改变。
shell的重定向功能是通过在fork和exec中间重定向标准输入、输出、错误来实现,如下面例程所示。
实际上使用管道的who | sort的也是一种重定向,只不过不是重定向到文件,而是重定向到另一个进程,这样就可以实现进程间的交互,这是通过将进程的输入输出重定向到管道来实现的。另外,socket的原理其实和管道很相似。
/* whotofile.c - fork a child, redirect stdout to file then execute who */ #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <sys/wait.h> int main() { int fd; int pid; printf( "about to execute who " ); pid = fork(); if( pid == 0 ) //这里是在子进程中做的,也可以不fork子进程直接做,见下一个例程 { close( 1 ); //先关闭文件描述符1,使得最低文件描述符变为1 creat( "file", 644 ); //在create一个新文件时会使用最低文件描述符 execlp( "who", "who", NULL );//执行execlp程序时是在同一进程中,因此继承文件描述符 } else { wait( NULL ); printf( "who execute finished! " ); } return 0; }
使用dup2的方法实现重定向:
/* stdinredir3.c - redirect stdin to file by "open-dup2-close" */ #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main() { int fd; char line[100]; fgets( line, 100, stdin ); printf( "%s", line ); fd = open( "/etc/passwd", O_RDONLY ); if( fd == -1 ) perror( "can open" ); dup2( fd, 0 ); close( fd ); fgets( line, 100, stdin ); printf( "%s", line ); fgets( line, 100, stdin ); printf( "%s", line ); fgets( line, 100, stdin ); printf( "%s", line ); return 0; }
以上是关于[Chapter10] 对重定向的理解的主要内容,如果未能解决你的问题,请参考以下文章