我有一个跨平台的Perl程序,它在win上启动win32 windows程序,在mac上启动macosx appliaction。
我使用system()
,它在mac上生成被调用程序的stdout,写在Perl程序的stdout中,这就是我想要的。
在Windows上,似乎没有办法让stdout成为Windows程序。所以作为替代方案,我让程序写入日志文件而不是,我希望Perl从日志文件中读取(因为它被写入,被调用的程序可以运行一个小时),并将其重定向回Perl的标准输出,因此Win和Mac上的体验是一样的。
有人知道如何在Perl中实际执行此操作吗?我在想:
我可能会弄清楚#1和#2,但还不知道如何解决#3。
答案 0 :(得分:4)
以下是否符合您的初衷:stdout
win32计划也是stdout
的{{1}}(或者我是否误解了您原来的问题)?
perl
Perl程序捕获// Win32 console application printing to stdout
#include <stdio.h>
int main(int argc, char* argv[])
{
int idx;
for (idx=0; idx < 10; idx++) {
printf("Hello World!\n");
fflush(stdout);
}
return 0;
}
的Windows程序并重定向到stdout
:
stdout
答案 1 :(得分:2)
如果您需要捕获程序打印到STDOUT的输出,为什么不简单地使用反引号代替system()
?
my $stdout = `program_name`;
if ( $? ) {
print "Child process had an error";
}
答案 2 :(得分:2)
IPC::Run3
允许你为stdin提供东西并捕获stdout和stderr。
答案 3 :(得分:0)
您是否阅读过system的文档? system
不允许您捕获STDOUT
。 qx
确实如此。
另一方面,看起来你真的不想捕获STDOUT
。您似乎希望程序的输出显示在与Perl程序相同的终端窗口中。如果您在Windows上调用的程序确实将其输出打印到STDOUT
,并且如果您在cmd
窗口中运行Perl程序,那么这将自然发生。
答案 4 :(得分:0)
捕获fork调用的返回值以获取子进程ID。
my $pid = fork();
if ($pid == 0) { # child
system("command > logfile");
exit 0;
}
# else parent
do {
# ... apply File::Tail to logfile, print new output ...
while (process_is_active($pid));
然后有很多方法可以判断孩子什么时候结束。这是两个:
# 1. kill 0, $pid
sub process_is_active {
my ($pid) = @_;
return kill 0, $pid; # returns "number of processes successfully signalled"
}
有些系统比其他系统更好地实施kill 0,...
。
# 2. non-blocking waitpid
sub process_is_active {
use POSIX ':sys_wait_h';
my ($pid) = @_;
my $waitpid = waitpid $pid, WNOHANG;
return $waitpid == $pid;
}
第二个解决方案只能运行一次 - 在waitpid
检测到该流程完成并收到该流程后,如果您在该流程上再次调用它,它将返回-1
。
答案 5 :(得分:0)
不确定“get stdout”是什么意思,但是当从Windows命令行使用perl.exe运行时,这正确地将“foo”打印到标准输出:
perl -e "system 'echo foo'"
所以我认为只要你在命令窗口中运行Perl,并且在调用system
之前不要试图弄乱任何stdout文件句柄它应该有效。