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
相关产品推荐
相关产品推荐

