You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让命令行工具在尝试写入指定文件时执行失败?

当然可以实现!针对你的单元测试场景,有几个高效且贴合需求的方案,下面逐一说明:

方案1:通过LD_PRELOAD劫持系统调用(推荐用于单元测试)

这是篡改系统调用返回值最直接的用户态方案,不需要root权限,完全适配单元测试的轻量化需求。核心思路是编写一个小型共享库,拦截目标进程调用的unlink()、open()等系统调用,当操作指定文件时直接返回EPERM(对应"Permission denied"错误),其他情况正常执行原函数。

具体步骤:

  1. 编写拦截库的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);
    }
}
  1. 编译成共享库:
gcc -shared -fPIC -o file_block.so file_block.c -ldl
  1. 运行目标命令时加载该库:
LD_PRELOAD=./file_block.so your_command_to_test

此时,目标进程在尝试删除、创建或写入指定文件时,都会触发"Permission denied"错误,完全符合你的预期。

方案2:利用挂载绑定实现只读保护(无需编译代码)

如果不想编写C代码,可以借助Linux的挂载绑定功能,用一个只读文件覆盖目标路径,阻止进程修改它。这个方法需要root权限:

  1. 创建一个只读的占位文件:
touch /tmp/readonly_placeholder
chmod 444 /tmp/readonly_placeholder
  1. 绑定挂载到目标文件路径:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:32:31