例如,当我键入Cat hello.txt时,它只读取Cat并启动几乎一个内部循环,我键入的所有内容都会重复。像"ls"这样的单个命令可以很好地工作。我认为这与空间有关。我做错了什么?感谢
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define MAX_LENGTH 1024
#define DELIMS " trn"
int main(int argc, char *argv[])
{
char line[MAX_LENGTH];
int loop = 1;
int pid;
int status;
char *cmd;
while (1)
{
status = 0;
printf("Ben$ ");
// printf("%dn",pid );
if (!fgets(line, MAX_LENGTH, stdin))
{
loop = 0;
break;
}
pid = fork();
if (pid == 0)
{
if ((cmd = strtok(line, DELIMS)))
{
// Clear errors
errno = 0;
if (strcmp(cmd, "cd") == 0)
{
char *arg = strtok(0, DELIMS);
if (!arg)
fprintf(stderr, "cd missing argument.n");
else
chdir(arg);
}
else if (strcmp(cmd, "exit") == 0)
{
_Exit(3);
printf("should have exitedn");
}
else
{
char *name[] = {
"/bin/bash",
"-c",
line, NULL
};
execvp(name[0], name);
}
if (errno)
perror("Command failed");
}
}
else
{
// printf("%dn",pid );
waitpid(pid, &status, 0);
if (status != 0)
{
break;
}
}
}
return 0;
}
调用strtok
,它通过用' '
替换第一个分隔符来"分解"字符串。因此,如果line
在strtok
调用之前有这个:
{ 'c', 'a', 't', ' ', 'h', 'e', 'l', 'l', 'o',
'.', 't', 'x', 't', 'n', ' ', <junk...> }
然后它就有了这个:
{ 'c', 'a', 't', ' ', 'h', 'e', 'l', 'l', 'o',
'.', 't', 'x', 't', 'n', ' ', <junk...> }
因此,可以使用"-c"
、"cat"
、NULL
调用"/bin/bash"
。
旁白:变量loop
未测试;在shell中,cd
和exit
命令必须在父级中实现,而不是在fork
调用之后实现;正如@shanet所指出的,您可以直接execvp
命令(对于非管道,没有重定向),尽管您必须首先拆分参数。(真正的shell也需要自己处理文件和管道,但显然这是以后的事情。:-)