问题
referring to the old homework question : /* implementing "/usr/bin/ps -ef | /usr/bin/more" */
using pipes.
#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. Is it inbuilt in execv that it reads from standard input before executing the command? I am unable to get this concept.
回答1:
Your question is based on a false premise -- execv
doesn't read from anywhere, nor does it need to. It is more
that reads from the stdin
it inherits across the call to execv
. 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. (Otherwise, /usr/bin/ps -ef | /usr/bin/more
wouldn't work.)
回答2:
In your second fork
call, I would change the code from this:
if (fork() == 0) {
close(fds[0]);
to this:
close(fds[0]);
if (fork() == 0) {
The argv[1]
for the ps
call should be -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. What the code is doing is modifying stdin
for more
and modifying stdout
for ps
. The stdout
for more
is the same as the current process (the parent). Thus, your program is redirecting ps
terminal output data to be the terminal input for more
.
The pipe
call returns two file descriptors that are connected to each other unidirectionally. When ps
writes to its stdout
, it is going to the dup
d fds[1]
. When more
reads from its stdin
, it is the dup
d fds[0]
. So, more
picks up the output of ps
.
来源:https://stackoverflow.com/questions/11373511/how-execv-gets-the-output-from-pipe