为什么一个软件包即使在升级时也能正常运行?

How*_*ard 31 linux inode files

假设我正在运行一个软件,然后我运行包管理器来升级软件,我注意到 Linux 没有关闭包升级的运行过程 - 它仍然运行良好。Linux 如何做到这一点?

jll*_*gre 37

原因是 Unix 在执行时不会锁定可执行文件,或者即使它像 Linux 一样锁定,此锁定适用于 inode,而不是文件名。这意味着即使在文件已被删除(实际上已取消链接)并替换为具有相同名称的新数据之后,保持其打开的进程仍会访问相同(旧)数据,这本质上是包更新所做的。

这是 Unix 和 Windows 之间的主要区别之一。后者无法更新被锁定的文件,因为它在文件名和 inode 之间缺少一个层,这使得更新甚至安装一些软件包非常麻烦,因为它通常需要完全重新启动。

  • 澄清一下,在 Linux 下你不能*修改*一个正在运行的可执行文件。但是您可以取消链接文件并将其替换为同名的新文件。 (11认同)
  • @jlliagre 除非我误解了,据我所知你不能:http://sprunge.us/egiR (4认同)
  • 不过,关于 NFTS 的一件好事 - 如果您从命令行或其他程序执行重命名,那么您可以将同名文件放回那里,并且不会影响打开原始文件的程序。(资源管理器中的重命名命令对此不起作用) (2认同)

Chr*_*own 18

可执行文件通常打开一次,附加到文件描述符,并且在单个执行期间没有重新打开其二进制文件的文件描述符。例如,如果您执行bashexec()通常只为/bin/bash一次指向的 inode 创建一个文件描述符- 在调用时。

这通常意味着对于在执行期间不尝试重新读取自身的简单二进制文件(通过使用调用它们的路径),缓存的内容作为悬空 inode 保持有效。这意味着本质上存在可执行文件先前版本的副本。

在更复杂的情况下,这可能会导致问题。例如,配置文件可能会被升级并随后重新读取,或者程序可能会通过执行它的路径重新执行自身。如果程序相互连接,也会出现问题,一个在升级前执行,一个在升级后执行(可能由第一个程序执行)。对于某些库也是如此。

但是,对于简单的用例,无需重新启动过程即可安全升级。