我正在编写一个shell模拟器,如果用户键入" lsh ls"我会运行命令ls
并忽略" lsh"这是由用户输入的。所以我使用readline库来获取输入,然后解析该行。然后我使用fork()和execvp()来运行ls命令。但是,当我输入lsh ls
时,我得到以下输出:
lsh: ls: No such file or directory
这是我的代码。我认为它将ls视为一个搜索文件,但我不明白为什么会这样做。
int main(){
pid_t id;
char* line;
char **args;
while(1){
line = readline("shell: > ");
if(strcmp(line,"exit") == 0){
break;
}
args = parse(line);
if(strcmp(args[0],"lsh") == 0){
id = fork();
if (id == 0){
if(execvp(args[1],args) < 0){
perro("no such command");
}
}
if(id > 0){
printf("I am the parent process, id %d\n",getppid());
}
}
free(line);
}
}
这是解析该行的函数。
#define LSH_TOK_BUFSIZE 64
#define LSH_TOK_DELIM " \t\r\n\a"
char **parse(char *line){
int bufsize = LSH_TOK_BUFSIZE, position = 0;
char **tokens = malloc(bufsize * sizeof(char*));
char *token;
if (!tokens) {
fprintf(stderr, "lsh: allocation error\n");
exit(EXIT_FAILURE);
}
token = strtok(line, " \n");
while (token != NULL) {
tokens[position] = token;
position++;
if (position >= bufsize) {
bufsize += LSH_TOK_BUFSIZE;
tokens = realloc(tokens, bufsize * sizeof(char*));
if (!tokens) {
fprintf(stderr, "lsh: allocation error\n");
exit(EXIT_FAILURE);
}
}
token = strtok(NULL, LSH_TOK_DELIM);
}
tokens[position] = NULL;
return tokens;
free(tokens);
}
答案 0 :(得分:3)
您看到的错误消息来自ls
,而不是lsh
。
你实际上已经:
char *args[] = { "lsh", "ls", 0 };
execvp(args[1], args);
这意味着您尝试执行ls
并成功执行此操作,但是您告诉ls
它被称为lsh
,因为argv[0]
设置为{{1}并请求它列出当前目录中的文件lsh
。因此,当ls
尝试查找文件时,它会失败,并使用您提供的命令名ls
报告错误。
你可以尝试这个(显示的输出是在macOS Sierra上获得的):
lsh
您需要使用:
$ cp /bin/ls xx97
$ ./xx97 23-ish
xx97: 23-ish: No such file or directory
$ rm xx97
然后你以正统的方式调用execvp(argv[1], &argv[1]);
。