最近我开始学习管道以获得乐趣。我已经陷入了几个部分,但我认为它很多,但我无法弄清楚如何获得输入转发到程序并同时从该程序输出。
目前我有这个处理管道的Perl脚本:
#!/usr/bin/perl
use strict;
use warnings;
use threads;
use FileHandle;
use IPC::Open2;
my $cv_program = "./test"; #test is the compiled C program below
my $cv_message = "";
my $cv_currentkey = "";
my $pid = open2(*PIN, *POUT, $cv_program);
my $thread_pipeout = threads->create('PIPEOUT', \&PIN);
$thread_pipeout->detach();
while($cv_currentkey ne "\n")
{
$cv_currentkey = getc(STDIN);
$cv_message .= $cv_currentkey;
}
print POUT $cv_message;
sub PIPEOUT
{
my $PIN = shift;
while(<PIN>)
{
print $_;
}
}
然后我有这个C程序只输出一些东西,请求一个字符串,然后打印该字符串:
#include <stdio.h>
int main(int argc, char const *argv[])
{
char input[100] = {0};
printf("This is a test.\n");
fgets(input, 100, stdin);
printf("You entered %s\n", input);
return 0;
}
运行Perl脚本的输出是:
~/Programming/Perl Pipes$ ./pipe.pl
Hello
This is a test.
You entered Hello
注意它在输入时会阻塞,然后在一个块中打印出所有内容。我需要它来打印这是一个测试,然后等待实际程序的输入。
另外我会注意到我在Perl脚本中使用getc而不是STDIN的原因是因为我找不到让STDIN阻止test.c的输出的方法,但是getc也没有用此刻也很好。
答案 0 :(得分:7)
我认为问题主要出在C端,而不是Perl端。 C看到它的标准输出是一个管道,因此在查询标准输入之前确保它刷新其标准输出缓冲区并不十分谨慎。
要解决此问题,您应该只需添加以下行:
fflush(stdout);
在第一个printf
之后和fgets
之前。
(免责声明:未经测试。)