为什么这两个execvp会产生不同的结果?

为什么这两个execvp会产生不同的结果?,c,posix,C,Posix,我想知道为什么下面的结果不同: char *const temp[] = {"cal","4","2019",NULL}; execvp(temp[0],temp); perror("Return from execlp not expected"); exit(EXIT_FAILURE); 执行时,将生成仅包含4月份的日历 char *const temp[] = {"cal"}; char *const temp2[] ={"4","2019",NULL};

我想知道为什么下面的结果不同:

char *const temp[] = {"cal","4","2019",NULL};


    execvp(temp[0],temp);
    perror("Return from execlp not expected");
    exit(EXIT_FAILURE);
执行时,将生成仅包含4月份的日历

char *const temp[] = {"cal"};
char *const temp2[] ={"4","2019",NULL};

    execvp(temp[0],temp2);
    perror("Return from execlp not expected");
    exit(EXIT_FAILURE);
执行时,将生成包含所有月份的日历

我想让第二个表单正常工作,至于我的问题,我有两个数组,一个用来存储所有命令,另一个用来存储命令的所有参数。乙二醇

array1[0] = command
array2[0] = arg1 ar2 arg3  // the arguments for the command in array1[0]
在循环中,直到我到达命令数组的末尾,使用fork并在子类中执行这些命令,以便我可以遍历并执行数组中的所有命令。

根据

execv()、execvp()和execvpe()函数提供了 指向表示参数列表的以null结尾的字符串的指针 可用于新程序第一个论点,按照惯例, 应指向与正在执行的文件关联的文件名。 指针数组必须由空指针终止


argv[0]
始终被假定为程序的名称,即使在您的案例中,
execvp
没有使用它。
cal
程序本身开始从
argv[1]
解释命令行。(见@kiran Biradar回答。)

您需要将参数(指向参数的指针)复制到一个更大的数组中,并为
argv[0]
设置一个伪参数。下面是一些简短的代码:

char **combine_args(char *arg0, char **tail) {
    size_t n = 0;
    while(tail[n]) ++n;
    char **ret = malloc(sizeof(char*)*(n+2));
    ret[0] = arg0;
    memcpy(ret + 1, tail, sizeof(char*)*n);
    ret[n+1] = 0;
    return ret;
}
接下来,您可以这样使用它:

char *const temp[] = {"cal"};
char *const temp2[] ={"4","2019",NULL};

char **argv = combine_args(temp[0], temp2);

execvp(argv[0], argv);
perror("Return from execlp not expected");
exit(EXIT_FAILURE);
如果在循环中执行此操作,并且可以更改
temp2
数组,则可以这样执行,而无需任何分配:

char *const temp[] = {"cal", "cal2", "cal3", NULL};
char *temp2[] ={NULL, "4","2019",NULL};

for(int i = 0; temp[i]; ++i)
{
    // ... fork here ...
    {
        temp2[0] = temp[i];
        execvp(temp2[0], temp2);
        perror("Return from execlp not expected");
        exit(EXIT_FAILURE);
    }
}

argv[0]
始终被假定为程序的名称,即使在您的案例中,
execvp
没有使用它。
cal
程序本身开始从
argv[1]
解释命令行。感谢您的回复,我如何更改它,使我可以在一个数组中使用命令,在另一个数组中使用参数,但仍然使用execvp执行。
char *const temp[] = {"cal", "cal2", "cal3", NULL};
char *temp2[] ={NULL, "4","2019",NULL};

for(int i = 0; temp[i]; ++i)
{
    // ... fork here ...
    {
        temp2[0] = temp[i];
        execvp(temp2[0], temp2);
        perror("Return from execlp not expected");
        exit(EXIT_FAILURE);
    }
}