是否可以使用重定向到stdin来通过命名管道读取间歇发送的数据?
我想做的是:
$ mkfifo pipe
$ ./test < pipe
在另一个终端:
$ cat datafile > pipe
$ cat datafile > pipe
将重复信息转储到管道中。这只是第一次有效。
这是一个显示行为的测试演示程序:
int main(int argc, char *argv[]) {
char input_string[30];
while(1) {
while( cin.read(input_string, 30) || cin.gcount()!=0 ) {
cout << "!" << endl;
}
}
return 1;
}
那么,发生了什么?重定向是否仅提供单个发送到管道的内容?我已经编写了一个实际生产代码的版本,它将管道名称作为参数,并保持打开以便以这种方式编写,也许这就是答案。但我想知道是否有办法通过重定向来实现这一目标。
答案 0 :(得分:1)
当您从管道重定向输入时,如下所示:
./test < pipe
shell打开管道进行读取,然后启动程序。但是在编写器存在之前打开管道才会完成 - 即open(2)
阻塞。当另一个进程打开管道进行写入时,原始open
调用完成,两者可以进行通信。当作者关闭管道的末端时,读取端也会关闭 - 读者得到一个EOF。
一旦完成该循环,您可以重新打开管道进行读取并开始另一个循环,但您必须自己完成。因此,如果您正在阅读stdin,则必须重新启动程序。或者,您可以在另一个文件描述符上重新打开管道,例如:
// Error checking omitted for expository purposes
int main(int argc, char **argv)
{
while(1)
{
int fd = open("pipe", O_RDONLY);
char buffer[30];
int n;
while((n = read(fd, buffer, sizeof(buffer)) > 0)
{
// Process input
}
close(fd);
}
return 0;
}
如果要将原始I / O包装在stdio FILE*
中,可以使用fdopen(3)
;我不知道如何将文件描述符包装在C ++流对象中,尽管它可能是可能的。
答案 1 :(得分:0)
$ cat datafile > pipe
将数据文件的内容发送到管道,并发送EOF(文件末尾)。此时重定向已关闭,之后推送到管道的数据不再重定向到./test
。