【发布时间】:2020-05-11 09:44:57
【问题描述】:
我正在尝试编写一个程序来执行 argv 中给出的任何内容。但是,当我实际运行 execvp 时,它没有给出任何输出,也没有产生任何错误。这是我的程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
int main (int argc, char * argv[]) {
char * args[argc];
for (int i = 0; i < argc - 1; ++i)
args[i] = strdup(argv[i+1]);
args[argc-1] = malloc(1);
*args[argc-1] = '\0';
printf("%s\n", args[argc-1]);
int rc = fork();
if (rc == 0)
execvp(args[0], args);
}
我运行 ./exec ls 时产生的输出只是一个空行。但是,如果我运行一个将 ls 硬编码到数组中的程序,它就可以正常工作。为什么这个程序没有列出目录的内容?
【问题讨论】:
-
如果你给出
ls的完整路径?你永远不会检查调用是否成功。 -
你为什么要重复参数——真的没有必要这样做,
char args[argc];是一个指针不足的要求;你需要char args[argc + 1];,所以你可以设置args[argc] = NULL;。使用args[argc - 1]和 mallocing 单个字节等会让人感到困惑。您的代码仔细打印args[argc - 1]中的空字符串,后跟换行符,说明您看到的内容。execvp()失败(但您没有发现这一点)。它失败了,因为你传递的参数列表没有正确地以空值结尾——你必须有args[argc] == NULL。 -
基本调试技巧:(1)检查系统调用是否正常; (2) 在执行函数之前将参数打印到
execvp()等。 —— 请注意,我没有篇幅指出您的for (int i = 0; i < argc - 1; i++)循环忽略了您传递给程序的最后一个参数。这可能没有帮助,特别是如果你在运行它时不提供任何参数(所以argc == 1,所以你甚至不复制argv[0])。 -
此外,尚不清楚您从
fork()中获得了什么好处——没有它,它会起作用,也可能会失败。该代码仅(间接)报告成功,因为在main()函数结束之前没有return,因此它每次都隐式返回 0(又名成功)。 -
经过@JonathanLeffler 的分析,这听起来是次要的,但您也忘记了释放使用 strdup 分配的指针。