如何让命令行工具在尝试写入指定文件时执行失败?
当然可以实现!针对你的单元测试场景,有几个高效且贴合需求的方案,下面逐一说明:
方案1:通过LD_PRELOAD劫持系统调用(推荐用于单元测试)
这是篡改系统调用返回值最直接的用户态方案,不需要root权限,完全适配单元测试的轻量化需求。核心思路是编写一个小型共享库,拦截目标进程调用的unlink()、open()等系统调用,当操作指定文件时直接返回EPERM(对应"Permission denied"错误),其他情况正常执行原函数。
具体步骤:
- 编写拦截库的C代码(例如命名为
file_block.c):
#define _GNU_SOURCE #include <dlfcn.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdarg.h> // 替换成你需要保护的目标文件路径 static const char* PROTECTED_FILE = "/path/to/your/target/file"; // 保存原系统调用的函数指针 int (*original_unlink)(const char* path) = NULL; int (*original_open)(const char* path, int flags, mode_t mode) = NULL; // 拦截unlink(),阻止删除目标文件 int unlink(const char* path) { if (!original_unlink) { original_unlink = dlsym(RTLD_NEXT, "unlink"); } if (strcmp(path, PROTECTED_FILE) == 0) { errno = EPERM; // 设置权限错误码 return -1; } return original_unlink(path); } // 拦截open(),阻止创建/写入目标文件 int open(const char* path, int flags, ...) { if (!original_open) { original_open = dlsym(RTLD_NEXT, "open"); } if (strcmp(path, PROTECTED_FILE) == 0 && (flags & (O_WRONLY | O_RDWR | O_CREAT))) { errno = EPERM; return -1; } // 处理O_CREAT需要的mode参数(可变参数适配) va_list args; mode_t mode = 0; if (flags & O_CREAT) { va_start(args, flags); mode = va_arg(args, mode_t); va_end(args); return original_open(path, flags, mode); } else { return original_open(path, flags, 0); } }
- 编译成共享库:
gcc -shared -fPIC -o file_block.so file_block.c -ldl
- 运行目标命令时加载该库:
LD_PRELOAD=./file_block.so your_command_to_test
此时,目标进程在尝试删除、创建或写入指定文件时,都会触发"Permission denied"错误,完全符合你的预期。
方案2:利用挂载绑定实现只读保护(无需编译代码)
如果不想编写C代码,可以借助Linux的挂载绑定功能,用一个只读文件覆盖目标路径,阻止进程修改它。这个方法需要root权限:
- 创建一个只读的占位文件:
touch /tmp/readonly_placeholder chmod 444 /tmp/readonly_placeholder
- 绑定挂载到目标文件路径:
sudo mount --bind /tmp/readonly_placeholder /path/to/your/target/file
测试时,目标进程尝试unlink()该文件会因挂载点存在而失败,创建/写入操作也会因权限不足报错。测试完成后记得卸载:
sudo umount /path/to/your/target/file
方案3:cgroups(不推荐,配置繁琐)
cgroups主要用于CPU、内存等资源限制,虽然cgroups v2的IO控制器可以实现文件访问限制,但配置流程复杂,需要编写规则、创建cgroup并将进程移入,远不如前两种方法高效,因此不建议在单元测试场景中使用。
内容的提问来源于stack exchange,提问作者guettli
相关产品推荐
相关产品推荐

