资讯详情

linux 运行的程序,把可执行文件或者动态库删除,程序会崩溃吗

📅 2026/11/2 8:56:19 | 华诺云谱 👁 阅读
linux 运行的程序,把可执行文件或者动态库删除,程序会崩溃吗
当程序运行的时候如果把可执行文件删除或者把这个程序依赖的动态库删除程序会继续正常运行还是会崩溃 ?当程序运行的时候如果将可执行文件覆盖或者将程序依赖的动态库覆盖程序会继续正常运行还是会崩溃 ?这两个问题中有两个变量一个是操作的对象可执行文件还是依赖库一个是操作的类型把文件删除还是把文件覆盖。删除文件只要文件还在用就不会真正删除cp new old可执行文件不允许动态库会崩溃mv new old均不会崩溃相当于把旧文件删除了创建了一个新文件两个文件的Inode号是不一样的。本文通过实验的方式来记录这 4 中情况。先列出结论如下操作对象删除覆盖 cp new old覆盖: mv new old可执行文件程序继续运行不崩溃操作失败提示文件忙程序继续运行不崩溃程序继续运行不崩溃动态库程序继续运行不崩溃程序崩溃程序继续运行不崩溃1 实验代码hello.c#include stdlib.h #include stdio.h #include string.h void say_hello() { printf(hello\n); return; }hello.c 中实现了一个函数 say_hello()将这个文件编译成一个动态库名字为 libhello.so。编译命令如下gcc -shared -fPIC -o libhello.so hello.chello.hvoid say_hello();hello.h 中是函数 say_hello() 的声明。这是使用 c 语言开发时常用的方式头文件中是函数的声明没有实现c 文件是是函数的实现。引用库的时候包含头文件然后再链接库。main.c#include stdlib.h #include stdio.h #include string.h #include unistd.h #include hello.h int main() { say_hello(); sleep(500); return 0; }main.c 中包含了 hello.h 头文件然后在编译的时候需要链接 libhello.so 这个动态库否则编译会失败提示找不到函数 say_hello() 的定义。编译命令如下gcc main.c libhello.so编译完成之后使用 ldd 查看 a.out 依赖的动态库时会提示 libhello.so 找不到这个时候我们还需要把 libhello.so 的路径设置到 LD_LIBRARY_PATH 环境变量中命令如下export LD_LIBRARY_PATH/home/wyl/exelib/:$LD_LIBRARY_PATH设置之后再使用 ldd 查看 a.out 依赖的库就能看奥 libhello.so 的位置了。2 实验记录2.1 删除可执行文件2.1.1 rm -rf 删除文件程序运行之后通过 ps -ef |grep a.out 可以查看进程的 pid。得到进程的 pid 之后就可以使用命令 cat /proc/[pid]/maps 看到进程的文件映射信息。如下图所示能看到进程中映射的 a.out 信息。然后删除 a.out再使用 cat /proc/[pid]/maps 查看文件映射信息可以看到 a.out 信息后边增加了一个标记 deleted。这个时候程序没有崩溃还在运行。a.out 也没有真正从磁盘删除只有 a.out 退出之后这个文件没有程序使用之后文件才会真正从磁盘删除。什么信息能佐证文件是不是真正从磁盘删除呢可以通过查看 inode 号。ls -i a.out 可以查看一个文件的 inode然后使用 lsof | grep xxx 来过滤这个 inode 号如果 inode 存在说明文件没有被删除否则说明被删除了。2.1.2 mv 移动文件mv 移动文件把文件移动到另外一个目录程序也会继续运行不会崩溃。如下图所示是程序运行之后后执行 mv a.out a.out-bak把文件重命名这个时候能够看到系统能自动识别出来文件发生了重命名。刚才的 mv我们并没有改变 a.out 的目录。我们继续移动 a.out-bak 移动到其它挂载点的目录下那么系统就显示 deleted 了跟把 a.out 删除现象是一样的。从上边的实验可以看出来使用 mv 移动文件的时候移动的目标位置也会影响系统的显示。a.out 原本的路径是 /home/wyl/exelib第一次移动的时候是用的命令是 mv a.out a.out-bak没有改变 a.out 的路径这个时候系统是能自动识别出来的。第二次移动的时候是用的命令是mv a.out-bak /run/改变了 a.out 的路径这个时候系统的显示和文件被删除是相同的。在 linux 中移动文件如果是在一个挂在点之内移动那么就相当于给文件重名名内核中的 inode 保持不变系统能自动识别如果文件的移动跨了挂载点那么就相当于将旧文件删除然后创建了一个新的文件。实验用的虚拟机的挂载点如下可以看到 /home/wyl/exelib 所在的挂载点和 /run 所在的挂载点是不一样的。看来Inode号是一个2.2 覆盖可执行文件想到文件覆盖的话我们能想到 cp new old 或者 mv new old。但是我们如果想要覆盖可执行文件的话使用 cp 无法操作成功提示文件正忙。我们只能使用 mv 的方式。使用 mv 的方式覆盖文件之后系统显示和文件被删除是一样的都是在 a.out 后边标记了 deleted。2.3 删除或覆盖动态库删除或者覆盖动态库的时候和删除或者覆盖可执行文件的时候现象是基本相同的。只有一点不一样就是 cp old.so new.so 时可以执行成功的并且这个操作会导致程序崩溃。mv 覆盖是删除旧的创建新的cp 覆盖是覆盖旧文件的内容。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑