我有一个来自第三方的命令行实用程序(它很大,用Java编写),我一直用它来帮助我处理一些数据.此实用程序需要行分隔文件中的信息,然后将处理后的数据输出到STDOUT.
在我的测试阶段,我写了一些Perl来创建一个充满要处理的信息的文件,然后将该文件发送到第三方实用程序,但是因为我接近将这些代码投入生产,我真的更喜欢直接将数据传输到此实用程序而不是首先将该数据写入文件,因为这将节省我不得不将不需要的信息写入磁盘的开销.我最近在这个板上问过我如何在Unix中做到这一点,但后来才意识到直接从Perl模块中运行它会非常方便.也许是这样的:
system(bin/someapp do-action --option1 some_value --input $piped_in_data)
目前我调用该实用程序如下:
bin/someapp do-action --option1 some_value --input some_file
基本上,我想要的是将所有数据写入变量或STDOUT,然后通过SAME Perl脚本或模块中的系统调用将其传输到Java应用程序.这将使我的代码更加流畅.如果没有它,我最终需要编写一个Perl脚本,该脚本调用一半的bash文件,反过来需要调用另一个Perl脚本来准备数据.如果可能的话,我很乐意在整个过程中留在Perl.有任何想法吗?
如果我正确地阅读你的问题,你想要产生一个进程,并能够写入它的stdin并从它的stdout读取.如果是这种情况,那么IPC :: Open2正是您所需要的.(另请参阅IPC :: Open3,您还需要从进程'stderr中读取.)
这是一些示例代码.我已经标记了你必须改变的区域.
#!/usr/bin/perl
use strict;
use warnings;
use IPC::Open2;
# Sample data -- ignore this.
my @words = qw(the quick brown fox jumped over the lazy dog);
# Automatically reap child processes. This is important when forking.
$SIG{'CHLD'} = 'IGNORE';
# Spawn the external process here. Change this to the process you need.
open2(*READER, *WRITER, "wc -c") or die "wc -c: $!";
# Fork into a child process. The child process will write the data, while the
# parent process reads data back from the process. We need to fork in case
# the process' output buffer fills up and it hangs waiting for someone to read
# its output. This could cause a deadlock.
my $pid;
defined($pid = fork()) or die "fork: $!";
if (!$pid) {
# This is the child.
# Close handle to process' stdout; the child doesn't need it.
close READER;
# Write out some data. Change this to print out your data.
print WRITER $words[rand(@words)], " " for (1..100000);
# Then close the handle to the process' stdin.
close WRITER;
# Terminate the child.
exit;
}
# Parent closes its handle to the process' stdin immediately! As long as one
# process has an open handle, the program on the receiving end of the data will
# never see EOF and may continue waiting.
close WRITER;
# Read in data from the process. Change this to whatever you need to do to
# process the incoming data.
print "READ: $_" while (<READER>);
# Close the handle to the process' stdin. After this call, the process should
# be finished executing and will terminate on its own.
close READER;
Run Code Online (Sandbox Code Playgroud)