文件描述符的寿命是多少?


11

如上所述这里,使用重定向open()写入到一个文件中。在外壳程序中创建了一个内部(?)文件描述符,然后在需要时使用它。

内部描述符是在脚本或Shell生命周期的整个过程中创建的吗?经过一段时间,多次操作等,它会被销毁吗?

我的意思是特别是shell本身为其内置操作打开的文件的文件描述符。是否为每个操作创建了描述符并打开了文件?他们保留了多久?例:

#!/bin/bash
>>x echo something
...do many other things not related to the file x
>>x echo something more

是否将第一个描述符实例保留到第二个操作?

我在终端中使用的外壳呢?有时,我每天开放一次会议,甚至可能持续数周。它是否仍保留我使用Shell内置程序操作的所有文件的描述符?

Answers:


4

简要地说:命令完成后,shell几乎肯定会立即关闭与重定向相关的文件描述符。


详细信息:没有明确提及关闭通过POSIX中的重定向打开的文件(据我所知)。但是不立即关闭它们并不是很有用。

任何启动命令的环境中规则都不允许传递额外的文件描述符。Shell将需要小心关闭任何多余的fd,因为在启动不应该包含它们的命令时会保存它。

对于通常的> filename输出重定向,即使保存了文件描述符,在启动每个命令时文件也可能被截断。而任何如果有关文件改名或删除同时保存文件描述符将指向一个错误的文件。

例如,如果第一个打开的fd echo保持打开状态,而第二个保持原样使用,则此操作将无法正确执行:

echo foo >> x; mv x y; echo bar >> x

用于启动外部程序的常用fork + exec模型也使在命令退出时自动关闭文件变得非常容易。fork()在调用exec()以实际命令替换子级之前,shell仅需要首先在子进程中打开所有必需的文件。子进程退出时,由它打开的所有文件都会自动关闭。


在中awk,尽管输出重定向的语法与shell相似,但是除非脚本已明确关闭,否则所有打开的文件都会保持打开状态,直到脚本退出。这只会打开foo一次,也不会在打印之间截断它:

awk 'BEGIN { print "a" > "foo"; print "b" > "foo" }'

6

完成后将它们关闭。Shell将为其运行的每个命令创建3个文件描述符0,1,2。这些只是数字,数字被重复使用。Shell将在重新使用描述符之前关闭文件。

文件描述符也传递给其他进程。而且,如果您在后台有一个进程,它将仍然具有文件描述符。

该示例使用3>&1,这意味着使文件描述符3引用描述符1当前引用的文件。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.