简体   繁体   English

execv如何从管道获取输出?

[英]How execv gets the output from pipe?

referring to the old homework question : /* implementing "/usr/bin/ps -ef | /usr/bin/more" */ using pipes. 指的是旧的作业问题: /* implementing "/usr/bin/ps -ef | /usr/bin/more" */使用管道/* 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]);  
} 

After redirecting the fd to standard output, how does execv reads from it. 将fd重定向到标准输出后,execv如何从中读取数据。 Is it inbuilt in execv that it reads from standard input before executing the command? 它是在execv中内置的,它在执行命令之前从标准输入中读取吗? I am unable to get this concept. 我无法理解这个概念。

Your question is based on a false premise -- execv doesn't read from anywhere, nor does it need to. 您的问题基于错误的前提execv不会从任何地方读取,也不需要读取。 It is more that reads from the stdin it inherits across the call to execv . 从它在对execv的调用中继承的stdin读取的内容more The reason more reads from stdin is because it's a filter and, like most filters, it defaults to reading from stdin if another input source isn't specified on the command line. stdin读取more的原因是因为它是一个过滤器,并且像大多数过滤器一样,如果未在命令行上指定其他输入源,则默认从stdin读取。 (Otherwise, /usr/bin/ps -ef | /usr/bin/more wouldn't work.) (否则, /usr/bin/ps -ef | /usr/bin/more将不起作用。)

In your second fork call, I would change the code from this: 在您的第二次fork调用中,我将更改代码为:

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

to this: 对此:

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

The argv[1] for the ps call should be -ef . ps调用的argv[1]应该是-ef

All programs will read from stdin to get terminal input and write to stdout to deliver data to the terminal, if they do not do anything to change the default settings for those streams. 如果所有程序都不做任何更改这些流的默认设置的操作,则所有程序将从stdin读取以获取终端输入,并写入stdout以将数据传递到终端。 What the code is doing is modifying stdin for more and modifying stdout for ps . 什么代码正在做的是改变stdinmore和修改stdoutps The stdout for more is the same as the current process (the parent). morestdout与当前进程(父进程)相同。 Thus, your program is redirecting ps terminal output data to be the terminal input for more . 因此,您的程序将ps终端输出数据重定向为more的终端输入。

The pipe call returns two file descriptors that are connected to each other unidirectionally. pipe调用返回两个单向连接的文件描述符。 When ps writes to its stdout , it is going to the dup d fds[1] . ps写入其stdout ,它将进入dup d fds[1] When more reads from its stdin , it is the dup d fds[0] . 当从其stdin读取more ,它就是dup d fds[0] So, more picks up the output of ps . 因此, more选择了ps的输出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM