在OS X上,就像在所有支持Linux的系统(Linux除外/dev/fd/x
)上一样,打开就像执行a一样dup(x)
,生成的fd或多或少指向与fd x上相同的打开文件描述,尤其是在文件内具有相同的偏移量。
Linux是这里的例外。在Linux上,/dev/fd/x
是一个符号链接/proc/self/fd/x
,并/proc/self/fd/x
是一个伪符号链接到FD X文件打开。在Linux上,当您执行a时open("/dev/fd/x", somemode)
,您将获得一个全新的打开文件描述,该描述与打开时相同x
。您获得的新fd与fd x没有任何关系。特别是,偏移量将位于文件的开头(O_APPEND
当然,除非您使用来打开它),并且模式(读/写/附加...)可能与fd x上的模式不同(您甚至可以得到与fd x上的内容大不相同,例如以相反模式打开管道的另一端)。(这也意味着,例如对于您无法打开()的套接字,该方法无效。)
因此,在Linux上,
exec 5<> file
echo test >&5
fd 5的偏移量位于文件末尾。如果你这样做
cat <&5
你什么都没有。
仍然在您执行以下操作时:
cat /dev/fd/5
您会看到,test
因为cat
获得了一个file
与fd 5无关的新只读fd。
在其他系统上
cat /dev/fd/5
cat
获取与fd 5重复的fd,因此文件末尾仍带有偏移量。
为什么它的工作原理与理由less
是,由于某种原因,less
做一个lseek()
对FD的文件的开头(没有一个lseek(1); lseek(0)
确定文件是否是可搜索的或没有)。
在这里,如果您希望两者都有不同的偏移量,则可能需要读一个fd并写一个fd:
exec 5< file 9>&1 > file
或者你将不得不重新打开该文件,如果仍然存在,或做一个lseek()
为less
一样。
ksh93
并且zsh
是唯一带有内置lseek()
运算符的shell :
cat <&5 <#((0)) # ksh93
{sysseek 0; cat} <&5 # zsh, zmodload zsh/system to enable that builtin
要么:
cat /dev/fd/5 5<#((0)) # ksh93
sysseek -u 5 0; cat /dev/fd/5 # zsh