覆盖可执行文件会影响运行原始可执行文件的进程吗?

Tim*_*Tim 4 process executable software-installation

当一个可执行文件在一个进程中运行时,如果该可执行文件被覆盖或删除,然后通过重新安装重新创建,该进程是否会重新运行新的可执行文件?

问题的答案是否取决于

  • 可执行文件是否在进程中作为服务/守护程序运行?

  • 操作系统,例如 Linux、Unix、...?

  • 重新安装是来自安装程序文件(例如deb,Ubuntumsi上的文件,Windows 上的文件)还是构建其源代码?

这里有些例子:

  • 在Ubuntu中,当一个进程运行的可执行文件,当我通过改写的可执行文件,通过手动重新安装configuremake以及make install在它的源代码,过程依然延续,而不是新的可执行文件来运行原有的可执行文件。

  • 我听说在Windwos 10中,当一个进程将一个可执行文件作为服务运行时,如果我们通过它的msi安装程序文件重新安装该可执行文件,那么服务进程将重新启动以运行新的可执行文件。在 Ubuntu 或 Debian 上从 .deb 文件安装是否相同或相似?

谢谢。

Gil*_*il' 5

这取决于内核和可执行文件的类型。它不依赖于可执行文件是如何启动或安装的。

在 Linux 上:

  • 对于本机可执行文件(即包含机器代码的二进制文件,由内核直接执行),可执行文件在运行时无法修改。

    $ cp /bin/sleep .
    $ ./sleep 999999 &
    $ echo >sleep
    sh: 1: cannot create sleep: Text file busy
    
    Run Code Online (Sandbox Code Playgroud)

    可以删除可执行文件(即取消链接)并在同一路径上创建一个新的可执行文件。与在文件仍处于打开状态时删除文件的任何其他情况一样,删除可执行文件不会影响正在运行的进程,并且不会实际将其从磁盘中删除,直到文件不再使用,即直到所有正在运行的实例程序退出。

  • 对于脚本(以 开头#!),可以在程序运行时修改脚本文件。这是否会影响程序取决于解释器如何读取脚本。如果它在开始执行之前将整个脚本读入自己的内存中,那么执行将不会受到影响。如果解释器按需读取脚本,那么执行可能会受到影响;sh这样做的一些实现。

许多其他 Unix 系统都采用这种方式,但不是全部。IIRC 旧版本的 Solaris 允许修改本机可执行文件,这通常会导致它崩溃。一些 Unix 变体,包括 HP/UX,甚至不允许删除当前正在运行的本机可执行文件。

大多数软件安装程序会在放置新的可执行文件之前小心地删除现有的可执行文件,而不是覆盖现有的二进制文件。例如做

rm /bin/target
cp target /bin
Run Code Online (Sandbox Code Playgroud)

而不仅仅是cp target /bin. 在installshell命令做的事情这样。但这并不理想,因为如果有人试图/bin/targetcp进程运行时执行,他们会得到一个损坏的程序。最好将文件复制到临时名称,然后将其重命名为最终名称。重命名文件(即将其移动到同一目录中,或更一般地将其移动到同一文件系统中)会删除先前的目标文件(如果存在)。dpkg例如,这就是工作原理。

cp target /bin/target.tmp
mv /bin/target.tmp /bin/target
Run Code Online (Sandbox Code Playgroud)