如何从调用该程序的 Perl 程序中观察正在运行的程序的 STDOUT?
我们试图弄清楚如何从 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";
我们希望能够每隔几分钟从文件句柄 $fh_dmcrcv 读取一次,或者在文件句柄上有活动时设置 AnyEvent io 触发器。
但是,当我尝试从文件句柄读取时,如果我使用类似以下的内容,它会被阻止:
foreach my $line (<$fh_dmcrcv>) {
print $line;
}
我们已经尝试了几种方法,不认为我们可以使用 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
脚本 process_files.pl 正在发出消息
running dcmrcv.bat
dcmrcv.bat started
。来自java程序的是: 启动服务器监听11112端口 11:55:13,495 INFO - 开始监听 0.0.0.0/0.0.0.0:11112
在这种情况下,我们只是为了这个问题而回显这些内容,实际上我们希望定期解析某些消息。并且永远不要重复其中任何一个。
任何见解都值得赞赏,
-Sam
We're trying to figure out how to run a java application from within a perl script but still be able to periodically read from the java app's 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";
We wanted to be able to read from the filehandle, $fh_dmcrcv, every few minutes or perhaps by setting up an AnyEvent io trigger when there is activity on the filehandle.
However, when I try and read from the filehandle, it blocks if I use something like this:
foreach my $line (<$fh_dmcrcv>) {
print $line;
}
We've tried several approaches, don't think we can use File::Tail, since it seems that module needs an actual file. The issue seems to be that $fh_dcmrcv is blocking us when we read from it, not really sure of the correct approach on how to achieve what we want.
EDIT #1
When we run our perl script we're seeing output like this:
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
The script, process_files.pl is emitting the msgs.:
running dcmrcv.bat
dcmrcv.bat started
The msgs. from the java program are:
Start Server listening on port 11112
11:55:13,495 INFO - Start listening on 0.0.0.0/0.0.0.0:11112
In this case we're echoing those out just for the sake of this question, really we want to periodically parse for certain msgs. and never echo any of them out.
Any insight is appreciated,
-Sam
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
大多数系统都支持 4 参数
select
函数(也很好地封装在 中)IO::Select
) 可以告诉您套接字句柄或管道句柄上是否有输入等待。在 Windows 中,仅在套接字上支持select
,这导致了这种拜占庭解决方案:示例:
您确定不想将命令输出写入临时文件吗?
Most systems support a 4-argument
select
function (also packaged nicely inIO::Select
) that can tell you whether there is input waiting on sockethandle or pipehandle. In Windows,select
is only supported on sockets, which leads to this byzantine solution:Example:
Are you sure you don't want to just write your command output to a temp file?
使用 IO::Select 或四个参数
select()
读取时读取不会阻塞。 编辑:没关系,你在 Windows 上,所以这不起作用。一种选择:让一个中间进程从此管道中读取数据,并保留一个中间文件,其中包含您需要的任何尾部长度。布莱赫。也就是说,从管道中“每隔几分钟”读取一次的最佳方法是每隔几秒读取一次。
Use IO::Select or four-argument
select()
to read when reading will not block. EDIT: Nevermind, you're on Windows, so this won't work. One option: have an intermediary process read from this pipe and keep an intermediary file filled with just whatever tail-length you need of it. Bleh.That said, the best way to read "every few minutes" from a pipe is to read from it every few seconds.
尝试用这个代替阅读:
问候
Try reading with this instead:
regards