用于执行后台进程的Shell项目

时间:2016-03-18 04:36:31

标签: c shell unix

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在后​​台执行流程?

1 个答案:

答案 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

您的程序没有实现globbingpipelines,并且无法运行带参数的程序(例如,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的源代码,当然还有实现它的主要系统调用。

顺便说一句,编译所有警告&amp;调试信息(gcc -Wall -Wextra -g)和经常使用调试器gdb)。