1

参考旧的作业问题:/* 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 中,它会从标准输入中读取?我无法理解这个概念。

4

2 回答 2

1

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

于 2012-07-07T08:42:27.950 回答
0

在您的第二次fork通话中,我将从以下代码更改代码:

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

对此:

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

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

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

pipe调用返回两个单向相互连接的文件描述符。当ps写入它stdout时,它会写入dupd fds[1]more从其读取时,stdin它是dupd fds[0]。因此,more获取 的输出ps

于 2012-07-07T08:48:41.413 回答