我尝试使用自定义execvp()
双指针作为输入执行**tokens
,而不是在“创建自定义外壳”分配上执行argv[]
,如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
int main(){
char *token;
char **tokens = malloc(sizeof(char*)*512); //512 is for the maximum input-command length
char *command=malloc(sizeof(char)*512);
int i = 0;
pid_t child_pid;
int status;
//***********take input from user*************************************
fgets(command,512,stdin);
//***********parse input*********************************************
token = strtok(command," \t");
while( token != NULL ) {
tokens[i]=token;
i ++;
token = strtok(NULL, " \t");
}
child_pid = fork();
if(child_pid == 0) {
/* This is done by the child process. */
execvp(tokens[0], tokens);
} else {
waitpid(child_pid, &status, WUNTRACED);
}
}
问题肯定在这条线上:
execvp(tokens[0], tokens);
,我只是不明白为什么无法执行并打印到我的 stdout
。
我已经尝试过了:
execvp("ls", tokens);
,效果很好。 这:
printf("%s\n", tokens[0]);
输出为(根据测试输入:ls
):
ls
答案 0 :(得分:2)
您的代码中有几个问题,包括:
传递给execvp()
的参数指针数组必须以空指针终止。您不确定。
如果缓冲区足够大,可以通过fgets
获得的字符串将包含所有字符,直到该行的换行符为止。您不能在令牌定界符中包括换行符,因此对于单字命令ls
,传递给execvp()
的命令等效于"ls\n"
, not "ls"
。 ls\n
在您的计算机上不太可能(但并非不可能)。
您不会检查execvp()
或任何其他函数的返回值,也不会处理任何错误。 execvp()
的特殊之处在于它仅在出现错误时才返回,但是如果您通过发出错误消息来处理该情况,则可以避免一些混乱。
我纠正了其中的前两个问题之后,您的程序为我成功运行了一个“ ls”命令。
答案 1 :(得分:1)
您需要使用sizeof(char *)
分配内存。
char **tokens = malloc(sizeof(char *)*512);
^^----------->Size of char pointer
到目前为止,您正在分配sizeof(char)
,从而调用未定义的行为。
还要考虑@ n.m指向的第一条评论