较新的系统都提供名为/dev/fd的目录,其目录项是名为0、1、2等的文件。打开文件/dev/fd/n等效于复制描述符n(假定描述符n是打开的)。
在下列函数调用中:
fd = open( "/dev/fd/0", mode );
大多数系统忽略它所指定的mode,而另外一些则要求mode必须是所涉及的文件(在这里则是标准输入)原先打开时所使用的mode的子集。
因为上面的打开等效于:
fd = dup( );
所以描述符0和fd共享同一文件表项。例如,若描述符0先前被打开为只读,那么我们也只能对fd进行读操作。即使系统忽略打开模式,并且下列调用成功:
fd = open( "/dev/fd/0", O_RDWR );
我们仍然不能对fd进行写操作。
我们也可以用/dev/fd作为路径名参数调用creat,这与调用open时,用O_CREAT作为第2个参数作用相同。例如,若程序调用creat,并且路径名参数是/dev/fd/1等,那么该程序仍能工作。
某写系统提供路径名/dev/stdin、/dev/stdout和/dev/stderr。这些等效于/dev/fd/0、/dev/fd/1和/dev/fd/2。
/dev/fd文件主要由shell使用,它允许使用路径名作为调用参数的程序,能用处理其他路径名的相同方式处理标准输入和输出。例如cat(1)程序对其命令行参数采取了一种特殊处理,它将单独的一个字符“-”解释为标准输入。例如:
filter file2 | cat file1 - file3 | lpr
首先cat读file1,接着读其标准输入(也就是filter file2命令的输出),然后读file3,如若支持/dev/fd,则可以删除cat对“-”的特殊处理,于是我们就可键入下列命令行:
filter file2 | cat file1 /dev/fd/ file3 | lpr
在命令行中用“-”作为一个参数,特指标准输入或标准输出,这已由很多程序采用。但是这会带来一些问题,例如若用“-”指定第一个文件名,那么它看来就像指定了命令行中的一个选项。/dev/fd则提高了文件名参数的一致性,也更加清晰。
本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。