假设 infile 包含特定文本,我将执行以下命令集:
执行
3<infile
猫-n
<&3
猫-n
<&3
cat 的第一个实例将显示文件的内容,但第二次似乎没有执行任何操作。为什么它们不同?
答案1
它们看起来像相同的命令,但它们不同的原因是系统状态由于第一个命令而发生了变化。具体来说,第一个文件cat
消耗了整个文件,因此第二个文件cat
没有剩余内容可读取,立即到达 EOF(文件结尾),然后退出。
这背后的原因是您在两次调用中使用完全相同的文件描述(您使用创建exec < infile
并分配给文件描述符的文件描述) 。与打开文件描述相关的内容之一是文件偏移量。因此,第一个读取整个文件,将偏移量保留在末尾,第二个尝试从文件末尾开始读取,但找不到任何可读取的内容。3
cat
cat
答案2
只是为了添加@jw013的好答案,它可能有助于认识到它与
{
cat -n
cat -n
} < infile
< file
是 的缩写0< file
,即使用文件描述符 0 而不是 3。
只是为了让事情变得有点混乱,这个版本:
exec 3< infile
cat -n /dev/fd/3
cat -n /dev/fd/3
行为有所不同,具体取决于运行它的操作系统和类型(infile
常规文件 vs 管道 vs 设备......)
在 Solaris 和大多数商业 Unices 上, anopen("/dev/fd/3")
或多或少相当于 a dup(3)
(因此< /dev/fd/3
与 大致相同<&3
),而在 Linux 上,对于常规文件,/dev/fd/3
被实现为原始文件的符号链接,因此open("/dev/fd/3")
从头开始重新打开它(并且可能具有与 fd 3) 不同的标志。