繁体   English   中英

execv如何从管道获取输出?

[英]How execv gets the output from pipe?

指的是旧的作业问题: /* 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]);  
} 

将fd重定向到标准输出后,execv如何从中读取数据。 它是在execv中内置的,它在执行命令之前从标准输入中读取吗? 我无法理解这个概念。

您的问题基于错误的前提execv不会从任何地方读取,也不需要读取。 从它在对execv的调用中继承的stdin读取的内容more stdin读取more的原因是因为它是一个过滤器,并且像大多数过滤器一样,如果未在命令行上指定其他输入源,则默认从stdin读取。 (否则, /usr/bin/ps -ef | /usr/bin/more将不起作用。)

在您的第二次fork调用中,我将更改代码为:

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

对此:

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

ps调用的argv[1]应该是-ef

如果所有程序都不做任何更改这些流的默认设置的操作,则所有程序将从stdin读取以获取终端输入,并写入stdout以将数据传递到终端。 什么代码正在做的是改变stdinmore和修改stdoutps morestdout与当前进程(父进程)相同。 因此,您的程序将ps终端输出数据重定向为more的终端输入。

pipe调用返回两个单向连接的文件描述符。 ps写入其stdout ,它将进入dup d fds[1] 当从其stdin读取more ,它就是dup d fds[0] 因此, more选择了ps的输出。

暂无
暂无

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

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