从 Perl 生成一个程序并通过 STDIN/STDOUT 与其通信
Spawn a program from Perl and communicate with it via STDIN/STDOUT
我有一个 C 程序,它只是 运行 一个从 STDIN 读取 JSON 结构并向 STDOUT 写入一行的循环。
为了支持front-end多种格式,想写一个Perl程序,反复读取数据,转换为JSON,提交给C程序,接收输出——就像我使用 qx//
调用 C 程序一样,只是每次都没有重新启动它。
描述了同样的问题,除了 parent 进程是在 C 中。我想知道 Perl 是否提供了一种更容易做到这一点的方法。如果可能的话,C 程序最好(但不是必需的)保持不变并且不知道它是由 Perl 还是从命令行 运行 派生的。
为了说明(注意 - 使用 Perl 作为 child,但希望同样的原则适用):
文件parent.pl
#!/usr/bin/env perl
use warnings;
use strict;
$|++;
# {{ spawn child.pl }}
while (1) {
print "Enter text to send to the child: ";
my $text = <>;
last if !defined $text;
# {{ send $text on some file descriptor to child.pl }}
# {{ receive $reply on some file descriptor from child.pl }}
}
文件child.pl
:
#!/usr/bin/env perl
use warnings;
use strict;
$|++;
while (my $line = <STDIN>) {
chomp $line;
$line .= ", back atcha.\n";
print $line;
}
执行:
$ parent.pl
Enter text to send to the child: hello
hello, back atcha.
Enter text to send to the child:
更新:
使用 open2
的注意事项,由 @ikegami 在下方和 Programming Perl / Interprocess Communication 中陈述,在我看来并不适用于此,因为:
- 我不关心 STDERR(这需要
open3
和 select
)
- 我控制 child 源代码,因此可以保证自动刷新发生。
- 协议严格是发送一行,接收一行。
鉴于原始问题的这些条件...
- 你不关心阅读 STDERR
- 您控制 child 源代码,因此可以保证自动刷新发生。
- 协议严格是发送一行,接收一行。
...以下将起作用。 (请注意,child 是用 Perl 编写的,但也可以是 C 语言。)
parent.pl
#!/usr/bin/env perl
use warnings;
use strict;
use IPC::Open2;
$|=1;
my $pid = open2(my $ifh, my $ofh, 'child.pl') or die;
while (1) {
print STDOUT "Enter text to send to the child: ";
my $message = <STDIN>;
last if !defined $message;
print $ofh $message; # comes with \n
my $reply = <$ifh>;
print STDOUT $reply;
}
close $ifh or die;
close $ofh or die;
waitpid $pid, 0;
child.pl
#!/usr/bin/env perl
use warnings;
use strict;
$|=1;
while (my $line = <STDIN>) {
chomp $line;
print STDOUT $line . ", back atcha.\n";
}
我有一个 C 程序,它只是 运行 一个从 STDIN 读取 JSON 结构并向 STDOUT 写入一行的循环。
为了支持front-end多种格式,想写一个Perl程序,反复读取数据,转换为JSON,提交给C程序,接收输出——就像我使用 qx//
调用 C 程序一样,只是每次都没有重新启动它。
为了说明(注意 - 使用 Perl 作为 child,但希望同样的原则适用):
文件parent.pl
#!/usr/bin/env perl
use warnings;
use strict;
$|++;
# {{ spawn child.pl }}
while (1) {
print "Enter text to send to the child: ";
my $text = <>;
last if !defined $text;
# {{ send $text on some file descriptor to child.pl }}
# {{ receive $reply on some file descriptor from child.pl }}
}
文件child.pl
:
#!/usr/bin/env perl
use warnings;
use strict;
$|++;
while (my $line = <STDIN>) {
chomp $line;
$line .= ", back atcha.\n";
print $line;
}
执行:
$ parent.pl
Enter text to send to the child: hello
hello, back atcha.
Enter text to send to the child:
更新:
使用 open2
的注意事项,由 @ikegami 在下方和 Programming Perl / Interprocess Communication 中陈述,在我看来并不适用于此,因为:
- 我不关心 STDERR(这需要
open3
和select
) - 我控制 child 源代码,因此可以保证自动刷新发生。
- 协议严格是发送一行,接收一行。
鉴于原始问题的这些条件...
- 你不关心阅读 STDERR
- 您控制 child 源代码,因此可以保证自动刷新发生。
- 协议严格是发送一行,接收一行。
...以下将起作用。 (请注意,child 是用 Perl 编写的,但也可以是 C 语言。)
parent.pl
#!/usr/bin/env perl
use warnings;
use strict;
use IPC::Open2;
$|=1;
my $pid = open2(my $ifh, my $ofh, 'child.pl') or die;
while (1) {
print STDOUT "Enter text to send to the child: ";
my $message = <STDIN>;
last if !defined $message;
print $ofh $message; # comes with \n
my $reply = <$ifh>;
print STDOUT $reply;
}
close $ifh or die;
close $ofh or die;
waitpid $pid, 0;
child.pl
#!/usr/bin/env perl
use warnings;
use strict;
$|=1;
while (my $line = <STDIN>) {
chomp $line;
print STDOUT $line . ", back atcha.\n";
}