命令 who | sort > prev 告诉shell同时执行who和sort,将who的输出直接送到sort的输入。who不一定要在sort命令开始读取和排序之前完成对utmp的分析。这两个进程以很小的时间间隔为单位来调度,它们和系统中的其它进程一起分享cpu时间。然后sort > prev告诉shell将sort的输出送到prev文件中。若此文件不存在则创建,若存在则替换其内容。
所有unix工具都使用文件描述符0(stdin)、1(stdout)和2(stderr);unix假设它们已经被打开(open),可以分别进行read、write操作了。注意括号里的stdin的意思是文件描述符(fd)0对应的流是(FILE*)stdin,两者是对应关系,而非等价。
默认情况下,程序的输出都是将结果写到文件描述符1,同时将错误消息写到文件描述符2,如果希望将进程的输出写到文件或另一个进程,就必须使用重定向的方法来实现。完成fd重定向的是shell而不是程序本身,重定向对程序来说是透明的,也不会收到重定向标记符;更通俗的来说就是重定向>是给shell看的,作用是通知shell改变>左边程序的输出流向。
4. 文件描述符(以下简称fd):fd是一个数组的索引号。每个进程都有一个保存打开文件句柄的数组(最低文件描述符原则,如果有空的fd,优先使用!),fd即为数组的下标索引,用来唯一标识一个已经打开的文件。
5.重定向常见的三种方法:
A.close then open
-----关闭之后这个fd就会空下来(下次关联之前无法使用),下次打开文件关联的时候就会优先使用此fd;
B.open...close....dup...close
-----先把文件打开随便关联一个fd,然后关闭你想重定向位置上的文件,然后此fd就空下来了,dup的作用就是关联文件和fd,此时相同的文件被关联了两处,所以要关闭一个(使用过固话分机的会熟悉些场景~);
C.open....dup2....close
-------此方式和B类似,dup2的作用与close...dup等价。
6.who > prev:我们知道,在shell中输入命令之后,shell会fork克隆一个新的进程,然后执行系统调用exec。exec将替换进程中运行的程序,但它不会改变进程的属性和进程中的所有的连接,进程的用户ID,优先级,文件描述符等都和运行exec之前一样。通俗的说就是一个人换了大脑,但是躯壳没有变~那么shell是怎么做到fd重定向的呢??? ---原来在fork和exec之间是有时间间隔的,shell会在fork之后就做好重定向,然后exec装入新程序运行who时,who就毫不知情的把结果输出到prev中去了。
最后附上实现代码:
1:redirect.c X
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
int pid;
int fd;
printf("about to run who into a file\n");
if ((pid = fork()) == -1)
{
perror("fork\n");
exit(1);
}
if (pid == 0)
{
close(1);
fd = creat("userlist",0644);
execlp("who","who",NULL);
perror("execlp");
exit(1);
}
wait(NULL);
printf("done running who.result in userlist\n");
return 0;
}