What Happens When You Delete an In‑Use File on Linux?
This article investigates Linux's handling of files that are in use—whether opened for reading, running as executables, or loaded as shared libraries—by experimenting with deletion, replacement, and modification, revealing how the kernel preserves file contents via inode references until all processes release them.
Origin
When deploying on Linux, I often replace an existing executable by deleting the old file, moving the new one into place, and restarting the service. Although this works, I wondered whether deleting a file that is still being executed could cause a crash.
Linux loads programs partially into memory and fetches missing pages from disk on demand. If the underlying file is removed, one might expect page faults to fail, yet in practice services continue to run after the file is deleted. This article explores why.
Prerequisite Knowledge
We assume each file has a single link count (no hard links). The inode number uniquely identifies a file; you can view it with ls -ilL filename.
Deleting a File That Is Being Read/Written
When a process has a file open, unlink() removes only the directory entry; the file’s data remains until the last descriptor is closed. The rm command uses unlink(), so deleting an open file does not affect the running process.
Example program that keeps data.txt open and repeatedly reads it:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFFER_SIZE 1024
int main(void) {
int fd;
int i = 0;
char buffer[BUFFER_SIZE];
if ((fd=open("data.txt", O_RDONLY)) == -1) {
printf("Open file Error
");
exit(1);
}
int pid = getpid();
int n = 0;
while(1) {
++i;
n = read(fd, buffer, BUFFER_SIZE-1);
if(n == -1) {
printf("read Error
");
exit(1);
}
buffer[n] = '\0';
printf("%d pid:%d, fd:%d, content: %s
", i, pid, fd, buffer);
sleep(1);
lseek(fd, 0L, SEEK_SET);
}
close(fd);
exit(0);
}While the program runs, deleting data.txt removes the directory entry but the process continues to read the original content because the kernel keeps the file data alive. Re‑creating a file with the same name does not affect the running process; the open file descriptor still points to the original inode.
Deleting a Running Executable
We compiled a simple program that prints its PID and a counter:
#include <stdio.h>
#include <unistd.h>
int main(void) {
int i = 0;
while(1) {
printf("ix:%d, pid:%d
", i, getpid());
++i;
sleep(1);
}
return 0;
}After starting the program (named pr_pid), we delete the executable file. The process continues to run without crashing. The /proc/<pid>/exe symlink still points to the original inode, and its MD5 checksum matches the deleted file, proving the kernel retains the executable’s contents until the process exits.
Attempting to overwrite a running executable with cp fails with “Text file busy”, because writing would modify the file’s contents, which the kernel protects for active executables.
Deleting a Used Shared Library
We built a shared library libshared.so containing an infinite loop, and a main program that calls a function from the library:
/* shared.c */
#include <stdio.h>
#include <unistd.h>
void justsit(void) {
int i = 0;
for(;;) {
printf("%d I am in shared
", i++);
sleep(1);
}
} /* main.c */
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
void justsit(void);
int main(int argc, char **argv) {
printf("My PID is %d
", getpid());
justsit();
return 0;
}Running the program shows the library being mapped into memory. Deleting libshared.so removes the directory entry, but the process continues to use the library because the kernel keeps the file data alive via the inode reference.
Writing new content to the shared library while it is in use succeeds (no “Text file busy”), but the running process eventually crashes because the memory‑mapped region and the on‑disk file become inconsistent.
Conclusion
Linux provides robust protection for files that are in use:
Deleting an opened regular file removes only its name; the data persists until all descriptors close.
Deleting a running executable removes the name but the kernel retains the executable’s contents for the active process.
Deleting a shared library behaves similarly; the library remains usable until the process releases it, but writing to the library while it is mapped can cause crashes.
When updating executables or shared libraries, use rm to remove the old file before placing the new one, or use package managers that follow this pattern. Avoid overwriting running executables with cp, and avoid writing to shared libraries that are currently loaded.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
MaGe Linux Operations
Founded in 2009, MaGe Education is a top Chinese high‑end IT training brand. Its graduates earn 12K+ RMB salaries, and the school has trained tens of thousands of students. It offers high‑pay courses in Linux cloud operations, Python full‑stack, automation, data analysis, AI, and Go high‑concurrency architecture. Thanks to quality courses and a solid reputation, it has talent partnerships with numerous internet firms.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
