簡體   English   中英

用管道組合兩個命令

[英]Combining two commands with a pipe

我試圖在一個(不存在的)命令中“合並”兩個命令並通過管道傳輸它。我的意思是..假設你有這兩個命令: grep text < file.txt | wc -l > out.txt grep text < file.txt | wc -l > out.txt ,可以表示這兩個命令的(不存在的)命令可能類似於(grepwc -l < file.txt)然后將行數輸出到 out.txt 中。 基本上這些 (grepwc) 命令應該與grep text < file.txt | wc -l > out.txt具有相同的行為grep text < file.txt | wc -l > out.txt grep text < file.txt | wc -l > out.txt但更短。

我嘗試過這樣的事情,但我認為我的方法離實現目標還很遠。 我使用了一個名為 commlist 的結構,它包含已經被 cmd、argc 和 argv 解析的命令。 inputfile 和 outputfile 是 open() 上使用的文件的路徑名。

我正在使用的結構。

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

和代碼:

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
  }
}

完整代碼在這里:

http://pastebin.com/tYGWwUjS

http://pastebin.com/sNJhEg2Y

你的方法確實有點過於復雜。 這可以通過一個子進程和一個管道來實現(就像在原始 shell 命令中一樣)。 讓我們來看看它:

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

這個

  • 創建管道
  • fork 兩個進程
  • 使 grep 寫入管道
  • 使 wc 從管道中讀取

但是只fork一個進程就足夠了,因為我們不需要返回父進程。 這導致以下代碼:

#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()失敗時才會到達exit()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM