使用管道在c中实现简单的shell?

时间:2014-03-02 18:53:59

标签: c

我正在使用forkexeclp在c中构建一个简单的shell。我将获得一组由管道分隔的命令。例如:ls -l | wc -l

我想使用管道进行内部进程通信。因此,ls -l的输出是wc -l的输入。可以通过管道分隔任意数量的命令。我不知道是否在子进程和父进程之间创建管道,然后当我从子进程获得输出时以某种方式将该输出传输到另一个子进程...我已经解析了输入。我怎么能这样做呢?

void excueteCommands() {

    int i, j;
    int fd[2];
    int cid1;

    commandNode* ptr = head;

    while (ptr != NULL) {

        for (i = 0; i <= pipeCount; i++) {

            cid1 = fork();

            if (!cid1) {

                if (i != 0) {

                    dup2(fd[i - 1][0], 0);
                }

                if (i != pipeCount) {

                    dup2(fd[i][1], 1);
                }

                for (j = 0; j < pipeCount; j++) {

                    close(fd[j][0]);
                    close(fd[j][1]);
                }

                execlp(ptr->command, ptr->args, NULL);
                exit(0);
            }

            ptr = ptr->next;
        }
    }

    for (i = 0; i < pipeCount; i++) {
        close(fd[i][0]);
        close(fd[i][1]);
    }

} 

1 个答案:

答案 0 :(得分:0)

去年我也有同样的任务。您无需单独处理从一个进程到另一个进程的输入和输出。只需在一系列进程之间初始化管道,输入和输出流就会发生。您只需要为第一个命令提供输入并从最后一个命令获取输出。

以下是我使用的代码段。

#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <unistd.h>
#include <stddef.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <sys/wait.h>

int exit_flag = 0;

#define ARG_SIZE 100



int main ()  
{

    int size = 1000,i,j;
    int pipe_count = 0;
    int fd[100][2],cid1,cid2,length,status;


    char string[][100] = {"ls","wc"};

    pipe_count = 1;

    if(pipe_count)
    {
        for(i = 0;i < pipe_count;i++)
        {
            pipe(fd[i]);
        }

        for(i = 0;i <= pipe_count;i++)
        {
            cid1 = fork();
            if(!cid1)
            {

                if(i!=0)
                {
                    dup2(fd[i-1][0],0);
                }


                if(i!=pipe_count)
                {
                    dup2(fd[i][1],1);
                }


                for(j = 0;j < pipe_count;j++)
                {   
                        close(fd[j][0]);
                        close(fd[j][1]);
                }

                execlp(string[i], string[i], NULL);
                exit(0);
            }


        }
        for(i = 0;i < pipe_count;i++)
        {
            close(fd[i][0]);
            close(fd[i][1]);
        }
        waitpid(cid1,&status,0);


    }
    else
    {
        execlp(string[0], string[0], NULL);
    }


    return 0;
}

在上面的代码中,string[]数组包含按顺序分隔'|'的所有命令。 fd[][2]是文件描述符数组。 fd[i][0]输入i+1命令,fd[i][1]输出ith命令。因此i的输出使用i+1管道输入fd[i]

我现在不记得如何处理dup2和close命令。你可能会在最近完成它们之后得到它们。我有任何疑问,然后我会尽力澄清。