我正在尝试使用自定义**tokens
双指针作为输入来执行execvp()
,而不是在"创建自定义shell"赋值上执行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("%sn", tokens[0]);
输出为(根据测试输入:ls
):
ls
您的代码中有几个问题,包括:
-
传递给
execvp()
的参数指针数组必须以null指针终止。你不能保证。 -
如果缓冲区足够大以容纳换行符,则通过
fgets
获得的字符串将包括该行换行符之前的所有字符。您的标记分隔符字符中不包括换行符,因此对于一个单词命令ls
,传递给execvp()
的命令等效于"lsn"
,而不是"ls"
。lsn
在您的机器上不太可能(但并非不可能)是可用的命令。 -
您不检查
execvp()
或任何其他函数的返回值,也不处理任何错误。execvp()
的特殊之处在于,它只在出现错误时返回,但如果您通过发出错误消息来处理这种情况,您会省去一些困惑。
在我纠正了前两个之后,你的程序成功地为我运行了一个"ls"命令。
您需要使用sizeof(char *)
来分配内存。
char **tokens = malloc(sizeof(char *)*512);
^^----------->Size of char pointer
到目前为止,您正在分配sizeof(char)
,从而调用未定义的行为。
同时考虑@n.m 指出的第一条评论