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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 01:31:34