powershell - Powershell 没有捕获 perl 的标准输出
问题描述
我在 powershell 中有以下简单脚本(比如在 下C:\Users\myusername\Desktop\tests\test.ps1
)
$counter = 0
while (1) {
$counter++
if ($counter % 2) {
[Console]::Error.WriteLine("($counter) This is an error")
} else {
echo "($counter) Some output"
}
sleep 1
}
我想以编程方式调用此脚本并将其标准输出和标准错误捕获到一个文件中(例如C:\Users\myusername\Desktop\test.log
)。为此,我编写了以下 powershell 脚本:
$psi = New-object System.Diagnostics.ProcessStartInfo
$psi.CreateNoWindow = $true
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.FileName = 'C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe'
$psi.Arguments = @('C:\Users\myusername\Desktop\tests\test.ps1')
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
$logAction = {
$time = Get-Date -Format o
Add-Content 'C:\Users\myusername\Desktop\test.log' "($time)[$($Event.MessageData)]: $($Event.SourceArgs.Data)"
}
Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived -Action $logAction -MessageData "STDERR" >$null
Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -Action $logAction -MessageData "STDOUT" >$null
$process.Start() >$null
$process.BeginErrorReadLine() >$null
$process.BeginOutputReadLine() >$null
$process.Id
文件内容test.log
如预期:
(2018-12-05T15:00:45.7615056+01:00)[STDERR]: (1) This is an error
(2018-12-05T15:00:47.0119743+01:00)[STDOUT]: (2) Some output
(2018-12-05T15:00:47.9497710+01:00)[STDERR]: (3) This is an error
(2018-12-05T15:00:49.8253980+01:00)[STDOUT]: (4) Some output
(2018-12-05T15:00:49.8253980+01:00)[STDERR]: (5) This is an error
(2018-12-05T15:00:51.2008546+01:00)[STDOUT]: (6) Some output
(2018-12-05T15:00:51.8260768+01:00)[STDERR]: (7) This is an error
(2018-12-05T15:01:03.6269252+01:00)[STDERR]:
(2018-12-05T15:01:03.6269252+01:00)[STDOUT]:
但现在有趣的部分来了。我有以下 perl 脚本(比如在 下),我使用Strawberry PerlC:\Users\myusername\Desktop\tests\test.pl
在 Windows 中运行,它非常类似于我的问题中的第一个 powershell 脚本:
#!/usr/bin/perl
use strict;
use warnings;
my $counter = 0;
while (1) {
$counter++;
if ($counter % 2) {
print STDERR "($counter) This is an error!\n";
} else {
print STDOUT "($counter) Some message\n";
}
sleep 1;
}
我还想以编程方式调用此脚本并将其标准输出和标准错误捕获到文件中。为此,我通过将$psi.FileName
和$psi.Arguments
值更新为:
$psi.FileName = 'C:\Strawberry\perl\bin\perl.exe'
$psi.Arguments = @('C:\Users\myusername\Desktop\tests\test.pl')
但是现在test.log
文件的内容不是我所期望的
(2018-12-05T14:14:53.9176561+01:00)[STDERR]: (1) This is an error!
(2018-12-05T14:14:55.7926306+01:00)[STDERR]: (3) This is an error!
(2018-12-05T14:14:57.9801317+01:00)[STDERR]: (5) This is an error!
(2018-12-05T14:15:22.2301618+01:00)[STDOUT]:
(2018-12-05T14:15:22.2301618+01:00)[STDERR]:
如您所见,标准输出没有被捕获。我完全不知道为什么会发生这种情况以及如何解决它。为什么它不适用于 perl 但它适用于 powershell?我怎样才能让它与 perl 一起工作?
我的 powershell 版本是 Windows 10 Pro 上的 5.1.17134.407。
解决方案
STDERR 通常设置为自动刷新,而 STDOUT 则不是。您的代码期望在编写时接收每个输出行。
尝试将以下 2 行添加到您的 Perl 脚本之后use warnings;
use IO::Handle;
STDOUT->autoflush(1);
推荐阅读
- vba - 在 PowerPoint 中将节点捕捉到网格
- node.js - Dialogflow 通过 NodeJS 传递参数
- java - 使用 JAVA 连接来自 .xml 文件的多个标签
- javascript - 如何提高 Chess.js 的 Minimax 的性能?
- flowtype - Flowtype:所有字段为Maybes的类型的简写
- c++ - 通过c ++中的字符串指针复制字符串变量中的字符串
- postgresql - 在 JSONB 日期字段上过滤 LoopBack API
- wordpress - 如何在 wp_head 中将备用、图标和清单链接排入队列?
- elasticsearch - 弹性搜索上的聚合太慢
- php - 如何同时显示数组键和值?