我有一个嵌入式 Linux 系统,可以从 USB 卡更新自身。界面程序检测到 USB 插入并查找升级后的可执行文件。我目前将其复制到本地文件,并在 rc5.d 中安装一些命令以在下次启动时将文件复制到现有 exe 上。然后我让软件重新启动。
有更好的方法吗?
我有一个嵌入式 Linux 系统,可以从 USB 卡更新自身。界面程序检测到 USB 插入并查找升级后的可执行文件。我目前将其复制到本地文件,并在 rc5.d 中安装一些命令以在下次启动时将文件复制到现有 exe 上。然后我让软件重新启动。
有更好的方法吗?
你不需要让它在下次启动时复制文件,相反,这个步骤可以正常运作:
应用程序会在 unlink()
后继续运行 - 直到所有正在执行的副本完成后,内核才会释放底层数据。
然后,您甚至可以只使用execve()
将当前正在运行的进程替换为新上传的版本。
程序正在运行中,只要首先使用rm
(unlink) 命令删除可执行文件,就可以替换它了。
不要用 cp
替换文件,因为那样做会导致问题。要么使用 mv
命令移动文件,或者更确保的方法是先使用 rm
删除文件,然后将新文件放到同一位置。如果您正在对嵌入式软件中的代码进行操作,则应该从 unlink(2)
命令开始。
Unix内核知道inode仍在使用中,他们会删除文件的目录条目,但他们不会释放inode(和数据块),直到inode引用计数归零,而当实例正在运行时,这种情况不会发生。
这在您的嵌入式系统中可能不是问题,但作为一般警告,请勿指望这适用于网络存储,除非在服务器本身上。
rm
命令删除可执行文件。否则,链接器将把新的可执行文件写入相同的 inode 中,你正在运行的进程可能会崩溃...就像我的一样。 - Mark Lakata在Linux中,当进程正在运行时,您可以安全地替换正在运行的可执行文件。只要进程正在运行,那个实例将继续使用“旧”的代码。所有对该应用程序的新调用都将使用“新”的代码。因此,简单地重新启动应用程序(或必要时重新启动设备)将使用新的副本。
请注意,如果您的应用程序将更改配置文件或库,则必须小心,因为它们可能不在内存中。在这种情况下,更安全的方法是让脚本执行您所提到的操作。
unlink()
函数(例如使用rm
命令)删除原始文件。 - j_random_hackerrm
删除现有文件或将现有文件移动到新名称来完成。简单地“替换”文件是不安全的。 - Mark Lakata
install
程序而不是cp
。请参考https://unix.stackexchange.com/a/95932/162125。 - undefined