为什么这两个“cat”命令的结果不同?

non*_*ist 12 shell io-redirection

假设 infile 包含特定文本,我将执行以下命令集:

执行 3<infile

猫 -n <&3

猫 -n <&3

cat 的第一个实例将显示文件的内容,但第二次似乎没有做任何事情。他们为什么不同?

jw0*_*013 29

它们看起来像相同的命令,但它们不同的原因是系统状态因第一个命令而改变。具体来说,第一个cat消耗了整个文件,所以第二个cat没有任何东西可以读取,立即命中 EOF(文件结尾)并退出。

这背后的原因是您正在使用完全相同的文件描述(你创建的exec < infile,并分配给该文件描述3了两种调用)cat。与打开文件描述相关的事情之一是文件偏移量。因此,第一个cat读取整个文件,在末尾留下偏移量,第二个尝试从文件末尾获取,但没有找到可读取的内容。


Sté*_*las 12

只是为了添加到@jw013 的好答案,它可能有助于意识到它与

{
   cat -n
   cat -n
} < infile
Run Code Online (Sandbox Code Playgroud)

< file的缩写0< file,即使用文件描述符 0 而不是 3。

只是为了混淆这个问题,这个版本:

exec 3< infile
cat -n /dev/fd/3
cat -n /dev/fd/3
Run Code Online (Sandbox Code Playgroud)

行为不同取决于你在运行它的操作系统和对类型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 不同的标志)。