为什么文件描述符只打开和读取一次?

tes*_*ter 7 bash file-descriptors stdin

为什么我们自己打开文件描述符重定向到stdin只能使用1次?请看下面的例子来理解我想说的话。使用 cat 命令读取一次后,第二次不会通过相同的文件描述符读取文件。

??$ exec 6< input.txt
??$ cat <&6
i am just string
and another string..
??$ cat <&6
??$
Run Code Online (Sandbox Code Playgroud)

Qua*_*odo 13

要打印文件,第一个cat必须阅读它直到结束。 exec 6< input.txt导致 shell 保留文件描述符,直到 shell 死亡或关闭它,因此当cat调用第二个时,文件偏移量仍指向文件的末尾,因此不会向 stdout 写入任何内容。

如果在基于 Linux 的系统上,您可以通过查看文件描述符信息来看到这种情况:

echo "File contents" > input.txt
exec 6< input.txt
cat "/proc/$$/fdinfo/6"
cat <&6
cat "/proc/$$/fdinfo/6"
cat <&6
Run Code Online (Sandbox Code Playgroud)

如果你执行那个脚本,你会得到类似的东西

pos:    0
flags:  0100000
mnt_id: 113
File contents
pos:    14
flags:  0100000
mnt_id: 113
Run Code Online (Sandbox Code Playgroud)

确认pos第二个cat执行时偏移量 ( ) 不是 0 ,而是指向它的末尾。

要重置偏移量,您可以exec 6< input.txtcats之间添加另一个。

  • ksh93 和 zsh 可以 *rewind* ksh93 有一个 `exec &lt;#((0))` 来倒带。并且`zsh` 有`sysseek 0`(在`zsh/system` 模块中),你总是可以执行另一个命令来执行`lseek()`。 (2认同)
  • 是的,您可以像其他重定向运算符一样执行 `exec 3&lt;#((0))` 或 `3&gt;#((0))`。 (2认同)