使用共享文件和 dup2() 将命令的标准输出通过管道传输到另一个命令的标准输入
Piping the stdout of a command to the stdin of another other using shared file and dup2()
我正在写一个带有两个参数的程序——命令的名称。该程序应该将第一个命令的输出重定向到文件 'tmp' 而不是执行它,而不是将第二个命令的标准输入重定向到 'tmp' 并执行第二个命令。
#include<unistd.h>
#include<fcntl.h>
#include<wait.h>
#include<stdio.h>
int main(int argc, char** argv){
int fd = open("tmp", O_RDWR |O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
int cpid = fork();
if(cpid == 0){
dup2(fd, 1);
execlp(argv[1], "", NULL);
}
wait(NULL);
//If we uncoment this line the program gives correct output
//fd = open("tmp", O_RDWR, S_IRUSR | S_IWUSR);
dup2(fd, 0);
execlp(argv[2], "", NULL);
}
但是当我 运行 程序喜欢 ./main ls wc
而不是
5 5 50
我得到输出 0 0 0
,这意味着 wc
命令从标准输入读取 0 个字节。
但是,如果我改为在同一个文件 'tmp' 上重新创建文件描述符,程序会给出正确的输出。如何解释这种行为?
这个问题基本上是 Can anyone explain a simple description regarding 'file descriptor' after fork()? 的重复,但由于这有点微妙,我将解释这个具体案例。
- 进程打开一个文件。这将创建一个 文件描述 。文件描述是文件和文件描述符之间的中间概念。它们没有直接暴露在 Unix API 中,但是除了它们指向的文件之外,它们还有一个重要的 属性,我们稍后会看到。
- child 写入此文件说明。 parent 等待。
- parent 从文件描述中读取。
在步骤 2 结束时,此文件描述中的文件位置为文件末尾。所以在第 3 步,parent 从文件末尾开始读取。
如果在 wait(NULL)
之后添加对 rewind(fd)
的调用,child 将从文件开头读取。
如果您使用新的 open
调用打开同一个文件,则会创建一个新的文件描述。 open
将新文件描述的位置放在文件的开头,除非您设置追加模式。
可以通过任意数量的文件描述符访问相同的文件描述,可能在不同的进程中。文件位置是文件描述的 属性,因此通过一个文件描述符移动它(读取、写入、查找)的任何操作也会为其他文件描述符移动它,即使在不同的进程中也是如此。
我正在写一个带有两个参数的程序——命令的名称。该程序应该将第一个命令的输出重定向到文件 'tmp' 而不是执行它,而不是将第二个命令的标准输入重定向到 'tmp' 并执行第二个命令。
#include<unistd.h>
#include<fcntl.h>
#include<wait.h>
#include<stdio.h>
int main(int argc, char** argv){
int fd = open("tmp", O_RDWR |O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR);
int cpid = fork();
if(cpid == 0){
dup2(fd, 1);
execlp(argv[1], "", NULL);
}
wait(NULL);
//If we uncoment this line the program gives correct output
//fd = open("tmp", O_RDWR, S_IRUSR | S_IWUSR);
dup2(fd, 0);
execlp(argv[2], "", NULL);
}
但是当我 运行 程序喜欢 ./main ls wc
而不是
5 5 50
我得到输出 0 0 0
,这意味着 wc
命令从标准输入读取 0 个字节。
但是,如果我改为在同一个文件 'tmp' 上重新创建文件描述符,程序会给出正确的输出。如何解释这种行为?
这个问题基本上是 Can anyone explain a simple description regarding 'file descriptor' after fork()? 的重复,但由于这有点微妙,我将解释这个具体案例。
- 进程打开一个文件。这将创建一个 文件描述 。文件描述是文件和文件描述符之间的中间概念。它们没有直接暴露在 Unix API 中,但是除了它们指向的文件之外,它们还有一个重要的 属性,我们稍后会看到。
- child 写入此文件说明。 parent 等待。
- parent 从文件描述中读取。
在步骤 2 结束时,此文件描述中的文件位置为文件末尾。所以在第 3 步,parent 从文件末尾开始读取。
如果在 wait(NULL)
之后添加对 rewind(fd)
的调用,child 将从文件开头读取。
如果您使用新的 open
调用打开同一个文件,则会创建一个新的文件描述。 open
将新文件描述的位置放在文件的开头,除非您设置追加模式。
可以通过任意数量的文件描述符访问相同的文件描述,可能在不同的进程中。文件位置是文件描述的 属性,因此通过一个文件描述符移动它(读取、写入、查找)的任何操作也会为其他文件描述符移动它,即使在不同的进程中也是如此。