Linux中如何锁定文件以防止重命名/删除且保留进程读写权限
在Linux下阻止用户修改已被进程打开的文件(重命名/删除)的方案
下面是几个实用的方案,既能保证你的进程正常读写文件,又能阻止用户对文件执行重命名、删除操作:
1. 限制文件所在目录的写权限
这是最直接的方案——Linux里删除、重命名文件本质是修改父目录的内容,只要用户没有父目录的写权限,就没法改动这些目录项。
- 操作示例:
假设你的文件路径是/app/logs/run.log,父目录为/app/logs,执行:# 移除其他用户对目录的写权限 chmod o-w /app/logs # 若要针对特定用户做精细限制,用setfacl setfacl -m u:testuser:-w /app/logs - 关键注意点:你的进程要先打开文件再修改目录权限,或者进程本身有足够权限访问文件。只要进程持有文件句柄,就算目录权限变更,依然能正常读写。
2. 将文件所在目录挂载为只读
用mount命令把父目录改成只读,用户就无法修改目录内的任何目录项(包括删文件、改文件名),但进程已打开的文件不受影响——因为文件句柄直接关联inode,和目录的挂载状态无关。
- 操作示例:
# 需要root权限执行 mount -o remount,ro /app/logs - 恢复方法:后续若要允许修改目录,执行:
mount -o remount,rw /app/logs - 适用场景:适合需要强限制的环境,会禁止所有非root用户修改目录内容。
3. 对父目录加排他锁(flock)
通过对文件的父目录加排他锁,阻止其他进程修改目录内容。注意这是建议性锁——如果用户使用的命令(比如rm、mv)不检查锁,这个方法可能无效,但对大部分遵守锁机制的程序会起作用。
- 代码示例(C语言):
#include <fcntl.h> #include <unistd.h> #include <stdio.h> int main() { // 打开父目录 int dir_fd = open("/app/logs", O_RDONLY); if (dir_fd == -1) { perror("Failed to open directory"); return 1; } // 加排他锁,进程运行期间持续持有 if (flock(dir_fd, LOCK_EX) == -1) { perror("Failed to lock directory"); close(dir_fd); return 1; } // 打开目标文件开始读写 int file_fd = open("/app/logs/run.log", O_RDWR); if (file_fd == -1) { perror("Failed to open file"); flock(dir_fd, LOCK_UN); close(dir_fd); return 1; } // 这里写入你的读写逻辑,比如循环写入日志 while (1) { write(file_fd, "Process running...\n", 18); sleep(5); } // 资源清理(实际进程可能不会执行到这里) close(file_fd); flock(dir_fd, LOCK_UN); close(dir_fd); return 0; } - 优点:无需修改系统权限,进程退出后自动释放锁,不会留下后遗症。
避坑提醒
- 不要用
chattr +i给文件加不可变属性:加了之后不仅用户无法删除,你的进程也没法修改文件内容,完全不符合需求。 - 进程打开文件后,务必用文件描述符操作:不要每次都通过路径重新打开——万一用户已重命名文件,路径会失效,但文件描述符依然有效。
内容的提问来源于stack exchange,提问作者tetektoza
相关产品推荐
相关产品推荐

