3

我试图在 C 中实现一个 shell。

到目前为止我做了什么:我有一个指针数组指向用户输入的所有命令,例如:

args[0]: sort
args[1]: <
args[2]: txtFile
args[3]: |
args[4]: grep
args[5]: key

然后我在每次找到“<”、“>”、“>>”或“|”时设置标志。然后我根据它们的使用方式使用这些标志来重定向、间接、附加或管道这些命令。

我的问题是,在处理以下命令时:

SHELL$: sort < txtFile | grep key

每次找到“<”、“>”、“>>”或“|”时,我应该创建多个进程吗?还是应该在处理完所有命令后创建这些进程?有人可以指出我正确的方向吗?

这是我到目前为止的代码:

else if(pid > 0) 
{ 
    /* parent process */
    if(!async) 
        waitpid(pid, NULL, 0);
    else 
        printf("this is an async call\n");

    if(PIPE_FLAG)
    {
        pid2 = fork();
        if( pid2 == 0)
        {
            waitpid(pid, NULL, 0);   
            close(c2p[1]);
            if(dup2(c2p[0], STDIN_FILENO) == -1){
                perror("dup2() failed");
                exit(-1);
            }
            execvp(nxt_args[0], nxt_args);
            perror("exec failed 2. ");          
            exit(-1);
        }
        else if( pid2 > 0)
        {
            close(c2p[0]);
            close(c2p[1]);
        }
        else
        {
            /* error occurred */
            perror("fork failed");
            exit(1);
        }
    }
}

我的第一个孩子处理 sort < txtFile,然后将其输出发送到管道。

4

3 回答 3

1

在将命令行分解为离散的命令和/或重定向之前,不要启动任何进程。否则,如果命令行格式错误,您可能会导致问题。

例如,假设您有一个destroy_files垃圾文件,并且可以选择说明它丢弃了哪些文件,以及一个fix_files修复它们的文件。假设用户将这些命令串在一起,例如destroy_files -v | fix_files < >. shell 最好说“嘿,这里有语法错误”而不运行任何东西......但是如果你在遇到分隔符时运行命令,对用户来说太糟糕了。您已经开始销毁他们的文件的过程。)

至于重定向,您不需要单独的进程来处理重定向。只需适当地设置 FD 0、1 和/或 2,操作系统就会处理字节混洗(根据需要进行阻塞或缓冲)。您所要做的就是等待进程结束。

于 2013-11-12T19:13:22.173 回答
1

让我们举个例子:

sort < txtFile | grep key

您必须创建一个进程sort,将其标准输入更改为读取txtFile,将其标准输出更改为管道的写入部分,然后执行程序sort

您还必须创建第二个进程,以便grep使用管道的读取部分并执行程序grep

所以你需要2个进程。但是为了设置第一个进程的标准输出,你需要解析管道。

编辑:

首先,创建管道。您必须第一次分叉以创建第一个进程,并为第一个进程正确设置标准输入和标准输出(重定向和写入管道的一部分)。然后你第二次 fork 父亲创建第二个进程,并将标准输入更改为管道的读取部分。你exec在子进程中执行sortgrep设置标准 I/O 之后。

于 2013-11-12T19:15:16.980 回答
0

创建进程时,您必须相应地设置文件描述符。启动大量进程是没有意义的,只是为了意识到命令行被搞砸了,因为分叉一个进程是昂贵的。

所以首先解析参数,然后你就会知道你需要多少个进程以及如何设置每个进程的文件描述符,然后你就可以运行它们了。

因此,在您的示例中,您将需要两个进程,一个管道和一个重定向。

于 2013-11-12T19:10:37.537 回答