execv怎么会从管道输出?(How execv gets the output from pipe

2019-10-16 23:16发布

指的是旧的作业问题: /* implementing "/usr/bin/ps -ef | /usr/bin/more" */使用管道。

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

int main()
{
  int fds[2];
  int child[2];
  char *argv[3];
  pipe(fds);
  if (fork()== 0) {
    close(fds[1]);
    close(STDIN_FILENO); dup(fds[0]); /* redirect standard input to fds[1] */
    argv[0] = "/bin/more";
    argv[1] = NULL;           /* check how the argv array is set */
    execv(argv[0], argv);// here how execv reads from stdin ??
    exit(0);


  }
  if (fork() == 0) {
    close(fds[0]);
    close(STDOUT_FILENO); dup(fds[1]);  /* redirect standard output to fds[0] */
    argv[0] = "/bin/ps";
    argv[1] = "-e"; argv[2] = NULL;
    execv(argv[0], argv);
    exit(0);

  }

  close(fds[1]);
  wait(&child[0]);
  wait(&child[0]);  
} 

在FD重定向到标准输出后,如何做execv从中读取。 它是内置在execv,它从标准输入执行命令前读? 我无法得到这个概念。

Answer 1:

你的问题是基于一个错误的前提- execv没有从任何地方阅读,也不需要。 这是more从读取stdin它横跨呼叫继承execv 。 其原因more从读取stdin是因为它是一个滤波器和,最喜欢的过滤器,则默认为从读取stdin ,如果没有在命令行上指定另一输入源。 (否则, /usr/bin/ps -ef | /usr/bin/more是行不通的。)



Answer 2:

在你的第二个fork电话,我会改变从这个代码:

  if (fork() == 0) {
    close(fds[0]);

为此:

  close(fds[0]);
  if (fork() == 0) {

所述argv[1]用于ps呼叫应-ef

所有程序将读取stdin以获得终端输入和写入stdout到数据传递给终端,如果他们没有做任何事情来改变默认设置为这些流。 什么代码正在做的是改变stdinmore和修改stdoutps 。 的stdoutmore相同当前进程(父)。 因此,你的程序重定向ps终端输出数据是用于终端输入more

pipe调用返回连接到彼此单向两个文件描述符。 当ps写入其stdout ,则要去dup d fds[1]more从其读取stdin ,它是dup d fds[0] 所以, more拿起输出ps



文章来源: How execv gets the output from pipe?