当我尝试写入文件描述符时,我无法理解发生了什么?好像覆盖了原来的内容?这是预期的行为吗?
我在下面的示例中复制了这一点:
$ echo "The quick brown fox ..." > example.txt
$ echo "The quick brown fox ..." >> example.txt
$ cat example.txt
The quick brown fox ...
The quick brown fox ...
$ exec 88<>example.txt
$ cat example.txt
The quick brown fox ...
The quick brown fox ...
$ echo "jumped" >&88
$ cat example.txt
jumped
ck brown fox ...
The quick brown fox ...
$ echo "jumped" >&88
$ cat example.txt
jumped
jumped
n fox ...
The quick brown fox ...
答案1
因为您没有对描述符 88 进行任何读取,所以当前查找位置为“0”,因此写入发生在该点。
相反,如果您在此之前读取了该文件,则会发生附加操作:
bash-4.2$ cat <&88
The quick brown fox ...
The quick brown fox ...
bash-4.2$ echo hello >&88
bash-4.2$ cat example.txt
The quick brown fox ...
The quick brown fox ...
hello
bash-4.2$ echo more >&88
bash-4.2$ cat example.txt
The quick brown fox ...
The quick brown fox ...
hello
more
答案2
正如 @Zoonose 正确指出的那样,每个文件描述符在其连接的文件中都有自己的读写光标位置。当您使用重定向(例如 )时,文件可以由 shell 打开<>
,也可以由程序(例如 )打开cat
。
但是您认为“文件描述符”的数字只是对内核中实际文件描述符的引用,一个文件描述符有多个这样的引用数字是完全正常的,无论是在单个进程内还是在进程之间。
因此,当您打开终端窗口(或通过 ssh 登录)时,您会从打开到终端的单个文件描述符开始,在 shell 进程中连接为 fd#0、fd#1 和 fd#2。 shell 启动的任何进程默认都会继承这些进程——除非您使用了管道或重定向。
重定向>>
将文件描述符标记为O_APPEND
,以便写入那filedescriptor 忽略光标并转到文件末尾。
重定向>
导致目标文件仅被截断一次,前任何写作都完成了。因此之后的任何写作通常情况下进入文件末尾之后的空白区域。
写入文件不是本身会导致截断;它们将简单地替换当前位置的任何内容,并在必要时拉伸文件结尾。
请注意,这somecmd >&88
将导致 somecmd 的标准输出 (fd#1) 与当前 shell 的 fd#88 共享文件描述符。这意味着它将共享O_APPEND
选项(如果存在)。它惯于使其再次被截断;那是一次性的事情。
你在这个案例中看到的是,没有额外的当您使用 , 时会截断>&88
,并且(因为 fd#88 没有使用打开>>
)它可以覆盖现有数据。