如何使用 Perl 启动 Win32 程序并将其输出重定向到 stdout?
我有一个跨平台的 Perl 程序,可以在 win 上启动 win32 windows 程序,在 mac 上启动 macosx 应用程序。
我使用system()
,它在mac上使被调用程序的stdout写入Perl程序的stdout中,这就是我想要的。
在 Windows 上,似乎没有办法获取 Windows 程序的标准输出。因此,作为替代方案,我让程序写入日志文件,并且我希望 Perl 从日志文件中读取(当写入时,调用的程序可以运行一个小时),并将其重定向回Perl的stdout,使得Win和Mac上的体验是一样的。
有人知道如何在 Perl 中实际做到这一点吗?我在想:
- 分叉进程
- File::Tail 日志文件,当数据进入时写入标准输出,以
- 某种方式弄清楚程序何时实际完成运行。
我可能可以找出#1 和#2,但还不知道如何解决#3。
I have a cross-platform Perl program that starts a win32 windows program on win, and a macosx appliaction on the mac.
I use system()
, which on the mac makes the stdout of the invoked program, be written in the stdout of the Perl program, which is what i want.
On Windows, it seems like there is no way to get the stdout a Windows program. So as an alternative, I'm having the program write to a logfile instead, and I'd like Perl to read from the logfile (as it's being written to, the invoked program could run for an hour), and redirect that back to Perl's stdout, so that the experience on Win and Mac is the same.
Does anybody know how to actually do this in Perl? I'm thinking:
- fork the process
- File::Tail the logfile, writing to stdout as data comes in
- somehow figure out when the program actually finished running.
I can probably figure out #1 and #2, but don't know yet how to tackle #3.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
以下内容是否能满足您的初衷:win32 程序的
stdout
也是perl
的stdout
(或者我误解了您原来的问题)?Perl 程序捕获 Windows 程序的
stdout
并重定向到stdout
:Would the following fulfill your original intention:
stdout
of win32 program is alsostdout
ofperl
(or did I misunderstand your original question)?Perl program capturing
stdout
of windows program and redirecting tostdout
:如果您需要捕获程序打印到 STDOUT 的输出,为什么不简单地使用反引号而不是
system()
呢?If you need to capture the output your programs print to STDOUT, why don't you simply use backticks instead of
system()
?IPC::Run3
允许您为标准输入提供内容并捕获标准输出和标准错误。IPC::Run3
lets you provide stuff for stdin and capture stdout and stderr.您是否阅读过 system 的文档?
system
不允许您捕获STDOUT
。qx
确实如此。另一方面,您似乎并不真正想要捕获
STDOUT
。您似乎希望程序的输出与 Perl 程序显示在同一终端窗口中。如果您在 Windows 上调用的程序确实将其输出打印到STDOUT
,并且您在cmd
窗口中运行 Perl 程序,那么这会自然发生。Have you read the docs for system?
system
does not let you captureSTDOUT
.qx
does.On the other hand, it does not look like you really want to capture
STDOUT
. It seems like you want the output from the program to appear in the same terminal window as the Perl program. If the program you are invoking on Windows does print its output toSTDOUT
and if you are running your Perl program in acmd
window, then this will happen naturally.捕获fork调用的返回值以获取子进程的进程ID。
然后有很多方法可以判断孩子何时完成。这里有两个:
某些系统在实现
kill 0,...
方面比其他系统做得更好。第二种解决方案只能工作一次——在
waitpid
检测到进程已完成并获取它之后,如果您在该进程上再次调用它,它将返回-1
。Capture the return value of the fork call to get the process ID of the child.
Then there are lots of ways to tell when the child has finished. Here are two:
Some systems do a better job of implementing
kill 0,...
than others.The second solution will only work once -- after
waitpid
detects that the process has finished and reaps it, it will return-1
if you call it again on that process.不太清楚“获取标准输出”是什么意思,但是当从 Windows 命令行使用 perl.exe 运行时,这会正确地将“foo”打印到标准输出:
所以我认为只要您在命令窗口中运行 Perl,并且在调用它应该工作之前,不要尝试弄乱任何标准输出文件句柄。
Not sure quite what you mean by "get the stdout", but this correctly prints "foo" to standard out when run using perl.exe from the Windows command line:
So I think as long as you run Perl in a command window, and don't try to mess with any of the stdout filehandles before calling
system
it should work.