带管结合两个命令 [英] Combining two commands with a pipe

查看:118
本文介绍了带管结合两个命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想合并在一个(不存在的)命令和管道it.By这两个命令我的意思..假设您有以下两条命令: grep的文字< file.txt的| WC -l> out.txt 的(不存在)的命令,可以重新present这两个命令可能是这样的(grepwc -l< file.txt的)然后输出线进out.txt的数目。基本上这些(grepwc)命令应该有相同的行为 grep的文字< file.txt的| WC -l> out.txt 但较短。

I'm trying to "merge" two commands in one (nonexistent) command and pipe it.By this I mean.. Suppose that you have these two commands: grep text < file.txt | wc -l > out.txt, the (nonexistent) command that could represent this two commands could be something like (grepwc -l < file.txt) which then outputs the number of lines into the out.txt. Basically these (grepwc) command should have the same behavior as the grep text < file.txt | wc -l > out.txt but shorter.

我想这样的事情,但我觉得我的做法是远远地实现目标。我使用了一个名为commlist结构,其中包含已被CMD,argc和argv解析的命令。 inputfile中和OUTPUTFILE是这些文件上使用的路径名的open()

I tried something like this, but I think my approach is far to accomplish the goal. I use a structure named commlist which contains the commands already parsed by cmd, argc and argv. inputfile and outputfile are the pathnames of the files used on open().

我使用的结构。

typedef struct command {
char *cmd;              
int argc;               
char *argv[MAXARGS+1];  
struct command *next;
} COMMAND;

和code:

void execute(COMMAND *commlist) {
  int fd[2];
  pid_t pid;
  int n_pipes=2; //pipes needed
  COMMAND *aux = commlist;

  int i;
  for(i=0;i<n_pipes; i++){
    int oldfd = 0;

    if(fd[0]!=0){
      close(fd[1]);
      oldfd = fd[0];
    }
      pipe(fd);

      if((pid=fork())<0){perror("Fork Failed");}
      else 
        if(pid == 0){

          if(inputfile!=NULL){
            int in = open(inputfile,O_RDONLY);
            dup2(in,STDIN_FILENO);
            inputfile = NULL;
          }

          if(outputfile != NULL){
            int out = open(outputfile, O_RDWR |O_CREAT | O_TRUNC, S_IRWXU);
            dup2(out,STDOUT_FILENO);
            outputfile = NULL;
          }

          if(oldfd)
            dup2(oldfd,STDIN_FILENO);

          if(commlist->cmd == "grepwc"){
            if(i==0){
              if(execlp("grep","grep","celio",NULL)<0){
                perror("Bad command");
                exit(1);    
              }
            }

            if(i==1){
              if(execlp("wc","wc","-l",NULL) < 0){
                perror("Bad command");
                exit(1);
              }
            }
          }
        }//child
  }
}

满code是在这里:

The full code is here:

http://pastebin.com/tYGWwUjS

http://pastebin.com/sNJhEg2Y

推荐答案

您的做法确实有点过于复杂。这可以只用一个子进程和单个管(正如在原壳命令)来实现。让我们来看看它:

Your approach is indeed a bit overcomplicated. This can be achieved with just one childprocess and a single pipe (just as in the original shell command). Let's have a look at it:

grep text < file.txt | wc -l > out.txt


  • 创建一个管道

  • 叉两种工艺

  • 的grep使得写到管道

  • 使WC从管道中读

但它足以叉只有一个进程,因为我们不需要返回到父进程。这将导致以下code:

But it is enough to fork only one process, since we do not need to return to the parent process. This results in the following code:

#include <stdlib.h>
#include <unistd.h>

int main (void) {
    int fd[2];

    pipe(fd);

    if (fork()) {
        // Child process
        dup2(fd[0], 0); // wc reads from the pipe
        close(fd[0]);
        close(fd[1]);
        execlp("wc", "wc", "-l", NULL);
    } else {
        // Parent process
        dup2(fd[1], 1); // grep writes to the pipe
        close(fd[0]);
        close(fd[1]);
        execlp("grep", "grep", "celio", NULL);
    }
    exit(EXIT_FAILURE);
}

退出()如果 execlp之一()的失败也只能达到。

The exit() is only reached if one of the execlp()'s fails.

这篇关于带管结合两个命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆