【发布时间】:2021-06-01 15:20:56
【问题描述】:
我正在尝试使用 C for linux 创建一个简单的 shell。我无法弄清楚为什么 execvp() 一直失败。我知道 execvp 不需要与参数一起传递的路径。我尝试通过 strtok 运行命令的 char 数组来遵循某人的建议。
我不断收到 execvp has failed: no such file or directory。我只是传递一个简单的“ls”作为我的测试命令。
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXARGS 20
#define CMDPROMPT "theshell>"
#define ARGPROMPT "Next argument: "
#define prompt(n) printf("%s", (n) == 0 ? CMDPROMPT : ARGPROMPT);
int main(int argc, char* argv[])
{
char arg[MAXARGS] = {0};
int i = 0,
should_run = 1, pid, exitstatus;
while (should_run)
{
prompt(*arg);
fgets(arg, MAXARGS, stdin);
char *arg = strtok(arg, " ");
char *arg_tok[MAXARGS];
while(arg)
{
arg_tok[i++] = arg;
arg = strtok(NULL, " ");
}
pid = fork();
switch(pid)
{
case -1:
perror("Fork Failed\n");
exit(1);
case 0:
execvp(arg_tok[0], arg_tok);
perror("execvp has failed");
exit(1);
default:
while( wait(&exitstatus) != pid );
printf("Child process exited with status %d, %d\n", exitstatus>>8, exitstatus&0377);
}
}
}
【问题讨论】:
-
退出
while()循环时,需要arg_tok[i] = NULL;或初始化char *arg_tok[MAXARGS] = {NULL};——最后一个参数之后的下一个指针必须是NULL。从man 3 execvp你看到"The array of pointers must be terminated by a null pointer." -
尝试了这两个选项,仍然收到相同的错误消息。如果我传递 arg 数组而不是 arg_tok,则 execvp 似乎接受了命令,但它不会执行并退出子进程。感谢您的回复。
-
还有
char *arg = strtok(arg, " ");SHADOWSchar arg[MAXARGS] = {0};。始终在启用警告的情况下进行编译,并为 gcc/cland 添加-Wshadow以捕获阴影变量。