先看一段代码:#include#include#include#include#include#include#includeintmain(){intfd1,fd2;fd2=open("p1.py",O_RDONLY,0);dup2(fd2,0);字符c;while(读(0,&c,1)>0)printf("%c",c);关闭(fd2);fd1=open("/dev/stdin",O_RDONLY);printf("%d\n",fd1);while(读(fd1,&c,1)>0)printf("%c",c);return0;}先说一下什么是文件描述符。每次linux进程打开一个文件,它都会返回一个文件描述符(整数)。这个描述符其实就是打开的文件在进程的描述符表中的偏移量。比如p是一个描述符表,1是一个描述符,那么p[1]可以索引到1个描述符对应的打开文件。有了这个偏移值(文件描述符),就可以快速找到并操作文件。(当然,实际情况是这个文件描述符可以索引到openfiletableentry,然后通过openfiletableentry索引到对应的v-node节点表项,而这个v-node节点表项代表了真正的文件。但你不需要只从逻辑的角度理解括号中的说明。)解释这个程序:1.首先,打开一个名为p1.py的文件。2、然后使用dup2函数使文件描述符0位置的指针指向文件描述符fd2位置的指针指向的文件。也就是说,原来是这样的:p[0]=&fiel1,p[fd2]=&file2,现在p[0]=p[fd2]=&file2。而我们都知道文件描述符0所在位置对应的文件file1就是标准输入文件/dev/stdin。那么这个函数的意思就是将标准输入重定向到p1.py文件中。然后使用标准输入,如scanf(),读取,则全部从文件p1.py中读取。3、然后读出这个文件的内容,输出到屏幕上。4.打开文件/dev/stdin,这是标准输入。5.读取此文件的内容并将其打印到屏幕上。预期结果是什么?执行到第5步应该停止,等待键盘输入。然后将输入打印到屏幕上。实际结果?它不是等待键盘输入,而是直接将p1.py文件的内容输出到屏幕上,也就是说和上面的输出是一样的!!!为什么???如何???我打开了一个文件,应该读取文件的内容。而且这个文件是标准输入,那么既然是标准输入(键盘输入),我还没输入呢,为什么输出结果呢???结果很奇怪。..这是因为标准输入文件/dev/stdin是一个链接文件!!!它存储了其他文件的地址!!!如果文件描述符指向的文件是一个普通文件,那么将文件描述符指向另一个文件就是真正指向另一个文件。而这里的文件描述符指向的是一个链接文件,那么将这个文件描述符指向另一个文件是什么意思呢???意思是它改变了这个链接文件中的内容(地址),但它仍然指向这个文件。只是它知道这是一个链接文件,所以它会访问链接文件中地址对应的文件。理解了上面的操作,就明白了。dup2只是修改了链接文件在文件中的地址,并没有真正指向其他文件,这也导致了一个问题,就是修改了链接文件,如果进程再次打开链接文件,存储的地址在链接文件消失之前,执行fd1=open("/dev/stdin",O_RDONLY);这个时候,p1.py其实是又打开了这个文件!!!因为文件/dev/stdin中存储的地址已经是文件p1.py的地址。..