slm*_*slm 6 io perl file-io exec parent-child
我们试图弄清楚如何在perl脚本中运行java应用程序,但仍然可以定期从java应用程序的STDOUT中读取.
print "running dcmrcv.bat\n";
open my $fh_dcmrcv, "-|", 'z:\apps\dcm4che\dcm4che-2.0.26\bin\dcmrcv.bat \
DCMRCV:11112 -dest z:\dcmrcv -journal z:\dcmrcv',
or die "could not execute dcmrcv: $!";
print "dcmrcv.bat started\n";
Run Code Online (Sandbox Code Playgroud)
我们希望能够每隔几分钟从文件句柄$ fh_dmcrcv中读取,或者可能通过在文件句柄上存在活动时设置AnyEvent io触发器来读取.
但是,当我尝试从文件句柄中读取时,如果我使用这样的东西,它就会阻塞:
foreach my $line (<$fh_dmcrcv>) {
print $line;
}
Run Code Online (Sandbox Code Playgroud)
我们已经尝试了几种方法,不要以为我们可以使用File :: Tail,因为模块似乎需要一个实际的文件.问题似乎是$ fh_dcmrcv在我们阅读时阻止了我们,并不确定如何实现我们想要的正确方法.
编辑#1
当我们运行perl脚本时,我们看到的输出如下:
Z:\projects\demo_2>process_files.pl
running dcmrcv.bat
dcmrcv.bat started
Start Server listening on port 11112
11:55:13,495 INFO - Start listening on 0.0.0.0/0.0.0.0:11112
Run Code Online (Sandbox Code Playgroud)
脚本process_files.pl正在发出消息:
running dcmrcv.bat
dcmrcv.bat started
Run Code Online (Sandbox Code Playgroud)
消息.从java程序是:启动服务器监听端口11112 11:55:13,495 INFO - 开始监听0.0.0.0/0.0.0.0:11112
在这种情况下,我们只是为了这个问题回应那些,我们真的想定期解析某些msgs.并且从不回应他们中的任何一个.
任何见解都表示赞赏,
萨姆
大多数系统都支持 4 参数select函数(也很好地封装在IO::Select),它可以告诉您套接字句柄或管道句柄上是否有输入等待。在 Windows 中,select仅在套接字上受支持,这导致了这个拜占庭解决方案:
例子:
use Socket;
use IO::Select;
use Time::HiRes;
$cmd = $^X . ' -MMath::BigInt -e "$_=1; '
. 'print qq/$_!=/,Math::BigInt->new($_)->bfac(),qq/\n\n\n/'
. ' for 4000..4100"';
socketpair A,B,AF_UNIX,SOCK_STREAM,PF_UNSPEC; # step 1
if (fork() == 0) {
open my $fh, '-|', $cmd; # step 2
while (<$fh>) {
print B; # step 3
}
close $fh;
exit $? >> 8;
}
$s = IO::Select->new();
$s->add(\*A);
for (;;) {
if ($s->can_read(0.25)) { # step 4
$line = <A>;
print "Do something with command output: $line";
} else {
print "No output now. Could be doing something else ...\n";
Time::HiRes::sleep(0.25);
}
}
Run Code Online (Sandbox Code Playgroud)
您确定不想将命令输出写入临时文件吗?
| 归档时间: |
|
| 查看次数: |
879 次 |
| 最近记录: |