【问题标题】:Shell command execution via forked process by passing variables through pipes通过管道传递变量,通过分叉进程执行 Shell 命令
【发布时间】:2017-06-12 01:45:10
【问题描述】:

这是一种无法实现的特殊场景。我想知道我犯了什么错误。

场景:
1. fork 一个子进程 2. 子进程执行shell命令(如cat排序文件) 3. shell 命令的参数通过管道从父进程传递(例如 g.cat 排序的文件输入)

我已经编写了下面的程序但是它显示的是文件名而不是打印出文件内容。但是它没有在屏幕上给出任何输出就挂起

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

int main(){

  int pipefd[2];
  pipe(pipefd);

  //create a pipe before you fork a child process
  pid_t cpid = fork();
  if(cpid < 0){
    perror("Fork");
  }
  else if(cpid == 0){
    printf("This is child process\n");

    close(pipefd[1]);
    close(0);

    dup2(pipefd[0],0);

    execlp("sort", "sort", NULL);

    exit(0);

  }
  else{
    printf("This is parent process\n");
    close(pipefd[0]);

    char *sort_array[] = {"hello", "amigos", "gracias", "hola"};
    for (int i=0; i<4; i++){
      write(pipefd[1],sort_array[i],strlen(sort_array[i]));
      write(pipefd[1], "\n",1);
    }


    int cstatus;
    wait(&cstatus);

  }


}

更新:
原始示例无效。我已更新为排序命令。
我正在尝试对内容进行排序。但是屏幕一直挂着,没有任何输出

【问题讨论】:

    标签: c linux pipe fork


    【解决方案1】:

    当您使用dup 时,您会使用管道输入模拟子进程stdin,因此当您在不带任何参数的情况下执行sort 时,它会从stdin 读取并读取直到它看到EOF,因此您必须写入管道然后关闭它。

    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <sys/wait.h>
    
    int main(){
    
       int pipefd[2];
       //create a pipe before you fork a child process
       pipe(pipefd);
    
       pid_t cpid = fork();
       if(cpid < 0){
           perror("Fork");
       } else if(cpid == 0) {
           printf("This is child process\n");
    
           close(pipefd[1]);
           close(0);
    
           dup2(pipefd[0],0);
    
           execlp("sort", "sort", NULL);
    
           exit(0);
    
      } else {
          printf("This is parent process\n");
          close(pipefd[0]);
    
          char *sort_array[] = {"hello", "amigos", "gracias", "hola"};
          for (int i=0; i<4; i++){
              write(pipefd[1],sort_array[i],strlen(sort_array[i]));
              write(pipefd[1], "\n",1);
          }
          close(pipefd[1]);
    
    
          int cstatus;
          wait(&cstatus);
    
        }
    }
    

    【讨论】:

    • 太傻了,我忘记了。真是糟糕的一天。我花了一整天的时间因为错过了关闭描述符:)。非常感谢
    【解决方案2】:
    pipe(pipefd);  // N.B. failed to check the return value, potential error
    
    //create a pipe before you fork a child process
    pid_t cpid = fork();
    if (cpid < 0)  // `if` is a language keyword, not a function, space after
    {              // opening brace on next line makes reading code easier
        perror("Fork");
    }
    else if (cpid == 0)
    {
        printf("This is child process\n");
    
        close(pipefd[1]);  // closing "write" end of pipe in child
        close(0);          // closing stdin in child
    
        dup2(pipefd[0],0); // returned handle is not stored, see https://linux.die.net/man/3/dup2
    
        execlp("cat", "cat", NULL);  // function prototype is int execlp(const char *file, const char *arg, ...);
                                     // what are you trying to accomplish?
    
        exit(0);
    }
    else
    {
        printf("This is parent process\n");
        close(pipefd[0]);  // close "read" end of pipe in parent process
    
        write(pipefd[1], "s.txt", 5);  // write text into pipe
    
        int cstatus;
        wait(&cstatus);    // wait for ??? something
    }
    

    您希望将名称传递到管道中的文件在哪里打开并写入输出?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-28
      • 1970-01-01
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多