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

C语言调用system()在Linux创建文件赋执行权限报错如何修复

错误根因

你的代码错误使用了strcpy函数:该函数会将源字符串完整覆盖到目标内存位置,不会做字符串追加。
逐行跟踪字符数组s的内容变化就能定位问题:

  • 执行strcpy(s, "touch ")后,s内容为touch
  • 执行strcpy(s, argv[1])后,原有touch 被直接覆盖,s内容变为你传入的参数abs
  • 执行strcpy(s, "; chmod a+x ")后,abs被覆盖,s内容变为; chmod a+x
  • 执行strcpy(s, argv[1])后,前面的内容再次被覆盖,s最终内容只剩abs

最终传给system()的命令就是单独的abs,shell找不到这个可执行文件,自然抛出abs: not found的报错。
另外原代码还有两个隐患:

  • 没有做参数个数校验,未传参数运行时会因为访问空指针触发段错误
  • 固定100字节缓冲区遇到长文件名时会发生缓冲区溢出
修复代码

字符串追加要使用strcat(更安全的版本是带长度限制的strncat),第一次初始化字符数组用strcpy,后续拼接内容全部用追加函数,同时加上基础的参数校验和溢出防护。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "运行格式: %s 目标文件名\n", argv[0]);
        return EXIT_FAILURE;
    }

    char cmd_buf[256];
    // 初始化命令字符串
    strcpy(cmd_buf, "touch ");
    // 逐段拼接命令,用strncat限制长度避免溢出
    strncat(cmd_buf, argv[1], sizeof(cmd_buf) - strlen(cmd_buf) - 1);
    strncat(cmd_buf, "; chmod a+x ", sizeof(cmd_buf) - strlen(cmd_buf) - 1);
    strncat(cmd_buf, argv[1], sizeof(cmd_buf) - strlen(cmd_buf) - 1);

    // 执行命令
    int exec_ret = system(cmd_buf);
    if (exec_ret == -1) {
        perror("system调用异常");
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
测试效果

编译运行:

gcc -o mkexec mkexec.c
./mkexec abs

执行完成后当前目录会生成abs文件,权限为所有用户可执行,通过ls -l abs可看到权限位为-rwxr-xr-x。

提示:该实现严格遵循要求必须使用system()的约束,如果文件名包含shell特殊字符会存在命令注入风险,无强制约束的场景下建议直接调用creat()/chmod()系统调用实现,不需要拉起shell。

内容的提问来源于stack exchange,提问作者Mykyta Abramenko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 04:03:26