带有pipe()函数的简单shell

时间:2014-11-06 20:15:21

标签: c bash shell

我正在编写一个简单的代码来实现unix / linux shell的管道功能。

#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

void
cisshPipe(char* command1[], char* command2[])

{
  int fd[2];//create array for two file descritors 
  pid_t childPid;//To set for child process
  pipe(fd);//To create pipeline here

  if((childPid=fork())==-1)
  {
       perror("fork here");
       exit(1);
  }

//The below is the real meat for this subroutine
  if(childPid==0)//If child process
  {
     close(fd[0]);//To close the input of child
     dup(fd[0]);//To duplicate the input, for the later process
  }
  else//For the real output
  {
    close(fd[1]);//To close the parent output first
    execvp(command2[],command2);
  }

  }

但是,我在“execvp(command2 [],command2)”上获得了一些关于预期表达式的编译错误。我认为这是由于我用来将子输出传递给父输入的dup()函数。有什么建议可以解决吗?

一些更新:

感谢约翰的回答。我解决了编译问题。但是当我输入“ls | sort”时它正在执行管道功能,我认为这仍然是dup()问题的传递。

2 个答案:

答案 0 :(得分:3)

execvp(command2[],command2);

[]是语法错误。也许你的意思是:

execvp(command2[0], command2);

答案 1 :(得分:1)

此代码有效,但不会执行所有可能的错误检查。类似于在将标准输入从(或标准输出)重定向到文件后关闭文件描述符的方式,当您使用管道时,如果dup()dup2()管道的一端对于标准输入或输出,您需要在执行命令之前关闭管道的两端。在子进程中创建管道时,您需要确保管道的两端也在父进程中关闭。

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

static inline void error(const char *msg)
{
    perror(msg);
    exit(EXIT_FAILURE);
}

static void
cisshPipe(char **command1, char **command2)
{
    int fd[2];
    pid_t childPid;
    if (pipe(fd) != 0)
        error("failed to create pipe");

    if ((childPid = fork()) == -1)
        error("failed to fork");

    if (childPid == 0)
    {
        dup2(fd[1], 1);
        close(fd[0]);
        close(fd[1]);
        execvp(command1[0], command1);
        error("failed to exec command 1");
    }
    else
    {
        dup2(fd[0], 0);
        close(fd[0]);
        close(fd[1]);
        execvp(command2[0], command2);
        error("failed to exec command 2");
    }
}

int main(void)
{
    char *ls[] = { "ls", 0 };
    char *sort[] = { "sort", "-r", 0 };
    cisshPipe(ls, sort);
    return 0;
}

示例输出:

xx.dSYM
xx.c
xx
xma.dSYM
xma.c
xma
ws-c11.c
…
am-pm.pl
2dv.dSYM
2dv.c
2dv
2da.dSYM
2da.c
2da