int main(void) {
char in[512];
pid_t id;
int status, y, x, i = 1;
char *f[512];
char *v;
while(1)
{
printf("shell>");
fgets(in,512, stdin);
int size = strlen(in);// calculate dim of in execpt null
in[size-1] = '\0'; //null at the end because ls\n not executable
v = strtok(in, " ");
f[0] = v;
while (v = strtok(NULL, " ")) {
f[i] = v;
i++;
}
f[i] = NULL;
y = strcmp(f[0],"exit");
if (y == 0)
break;
id = fork();
if (id==0) { //child
execvp(f[0],f);
perror("failure");
exit(1);
}
else //parent
{
x=strcmp(f[i-1],"&");
if (x != 0)
waitpid(id, &status, 0);
}
}
}
在这段代码中,我可以执行shell命令,但是我无法执行command &
部分。如何让execvp
在后台执行流程?
答案 0 :(得分:1)
阅读Advanced Linux Programming 。在现有程序(特别是shell)上使用strace(1)来了解他们正在做什么system calls。查看syscalls(2)列表,并更准确地阅读其中几个文档(请参阅intro(2) ...)。 研究一些现有free software shell 的源代码,例如sash& bash
请勿忘记系统调用(例如您对fork(2)的调用...)可能会失败。你应该处理失败,至少像:
id = fork();
if (id<0) { perror("fork"); exit(EXIT_FAILURE); };
关于结束&
的处理,您正在关注job control。详细了解process groups。
您的程序没有实现globbing或pipelines,并且无法运行带参数的程序(例如,ls a b
命令应该使用三个参数运行/bin/ls
每个shell应该"ls"
,"a"
,"b"
)。见glob(7)&amp; pipe(7)
不要指望我们做你的功课。你可能应该编写一个更大的程序(可能是一千行,几十个函数,几个带有指针的struct
,......),并首先考虑它的设计(这是研究现有的地方 shell实现可以帮助你)。特别是首先在一张纸(或一些白板)上列出一组要实现的重要功能和数据结构。
我建议首先对shell进行编码,以便能够运行像ls a b
这样的简单命令,实现globbing(所以接受ls *.c
)。完成并调试后,请考虑实现一些内置(特别是cd
),作业控制和管道。在学习之前,现有的 shell的源代码,当然还有实现它的主要系统调用。
gcc -Wall -Wextra -g
)和经常使用调试器(gdb
)。