使用execv()系统调用执行命令失败问题排查求助
代码中的错误分析及修复方案
1. 参数数组越界(execv失败的核心原因)
你定义了char *args[2];,但后续执行args[2] = NULL;时发生了数组越界访问——数组下标最大为1,写入下标2会破坏栈上的其他变量内存(比如path或last的存储),导致execv调用时参数结构异常,最终执行失败。
execv要求参数数组必须以NULL结尾,因此需要将args数组的大小调整为至少能容纳命令名、参数和终止符,修改为:
char *args[3];
2. removeTrailingLeadingSpaces函数实现无效
该函数意图去除字符串首尾空格,但由于C语言的参数传递是值拷贝,函数内部修改的input指针只是局部变量,并不会改变外部传入的指针(比如token)。而且strtok_r以空格为分隔符分割出的token本身就不会包含前导空格,因此removeTrailingLeadingSpaces(token)这一步完全多余,可直接删除。
如果需要正确实现去除首尾空格的功能,应修改函数为返回处理后的指针:
char* removeTrailingLeadingSpaces(char* input) { while(isspace((unsigned char)*input)) input++; if (*input == '\0') return input; int i = strlen(input) - 1; while(i >= 0 && isspace((unsigned char)input[i])) i--; input[i+1] = '\0'; return input; }
调用时改为:
input = removeTrailingLeadingSpaces(input);
3. path数组存在溢出风险
char path[10];的空间仅能容纳短命令路径,若用户输入更长的命令(比如/bin/python3)会导致缓冲区溢出,破坏内存。建议增大数组大小:
char path[256]; // 足够容纳绝大多数/bin下的命令路径
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <ctype.h> char* removeTrailingLeadingSpaces(char* input); int main () { printf("dash> "); char* input = NULL; size_t bufsize = 0; ssize_t characters = getline(&input, &bufsize, stdin); if (characters == -1) { perror("getline failed"); free(input); return 1; } input = removeTrailingLeadingSpaces(input); char *args[3]; char* last; char* token = strtok_r(input, " ", &last); if (!token) { free(input); return 0; } char path[256]; strcpy(path, "/bin/"); strcat(path, token); args[0] = path; args[1] = strtok_r(NULL, " ", &last); args[2] = NULL; int i = access(args[0], X_OK); printf("access result: %d\n", i); execv(args[0], args); perror("execv failed"); free(input); return 1; } char* removeTrailingLeadingSpaces(char* input) { while(isspace((unsigned char)*input)) input++; if (*input == '\0') return input; int i = strlen(input) - 1; while(i >= 0 && isspace((unsigned char)input[i])) i--; input[i+1] = '\0'; return input; }
额外说明
getline会自动分配内存,无需手动malloc;若手动分配,需检查返回值避免内存分配失败。- execv调用成功后不会返回,只有失败时才会执行后续代码,用
perror可打印具体错误原因(如权限不足、路径不存在等)。
内容的提问来源于stack exchange,提问作者TheCoder
相关产品推荐
相关产品推荐

