arc*_*ank 3 powershell stdout stderr
我想获得stdout
和stderr
运行一个Java进程,并看到了似乎是一个简单的,冷静的方式来做到这一点,但它没有工作:
$command = "java -jar secretserver-jconsole.jar -s 123456 Password"
Invoke-Expression $command -OutVariable output -ErrorVariable errors
Write-Host "stdout: $output"
Write-Host "stderr: $errors"
Run Code Online (Sandbox Code Playgroud)
没有显示$output
或$errors
。
我现在正在使用:
$output = cmd /c $command
Run Code Online (Sandbox Code Playgroud)
这确实让我得到了一些stdout
,但它并不理想,因为我想要$error
消息。
我什至尝试了这种精心设计的方法,但它似乎没有运行我认为的流程,因为它几乎立即返回,而且我知道正常流程任务几秒钟。它也没有显示输出或错误:
$psi = New-object System.Diagnostics.ProcessStartInfo
$psi.CreateNoWindow = $true
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.FileName = 'java'
$psi.Arguments = @("-jar","secretserver-jconsole.jar","-
s","123456","Password")
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
[void]$process.Start()
$output = $process.StandardOutput.ReadToEnd()
$process.WaitForExit()
Write-Host "stdout: $output"
(tried: adding:
do
$process.StandardOutput.ReadLine()
}
while (!$process.HasExited)
Run Code Online (Sandbox Code Playgroud)
注意:下面的解决方案假设了一个行为良好的外部实用程序:一个将数据发送到stdout,并将错误消息发送到stderr。如果给定的实用程序意外地将错误消息发送到 stdout,就像 OP 的情况一样,您必须自己解析 stdout 输出以提取错误消息。
$stdout = java -jar secretserver-jconsole.jar -s 123456 Password 2>($tmpFile=New-TemporaryFile)
$stderr = Get-Content $tmpFile; Remove-Item $tmpFile
Run Code Online (Sandbox Code Playgroud)
New-TemporaryFile
需要 PSv5,但您可以[io.path]::GetTempFileName()
在早期版本中使用。
请注意,$stdout
和$stderr
都将包含一个字符串数组,每个项目代表一个输出行。
外部实用程序的退出代码反映在 PowerShell 的自动$LASTEXITCODE
变量中。
请注意,合并捕获 stdout 和 stderr实际上更容易:
$stdoutAndStdErr = java -jar secretserver-jconsole.jar -s 123456 Password 2>&1
Run Code Online (Sandbox Code Playgroud)
注意:每个 stderr 行在结果中都表示为一个[System.Management.Automation.ErrorRecord]
实例,但它们的计算结果为字符串上下文中该行的内容。
至于你尝试了什么:
通常不需要将命令存储在字符串中(因此很少需要使用Invoke-Expression
,其使用可能有风险)。
--%
关闭 PowerShell 的解释 - 请参阅Get-Help about_Parsing
),$cmd = { ... }
),然后使用&
(call operator) 或.
(dot-sourcing operator)调用它- 前者为 PS 变量创建一个子作用域,后者才不是。在-OutVariable
与-ErrorVariable
常用的参数仅设计工作与PowerShell的输出流,而不是外界的输出和错误。
PowerShell 捕获 stdout 输出,就像它已发送到 PowerShell 的成功输出流一样,并将输出行视为字符串数组。
Stderr 输出通过(并且不会反映在 中$Error
),但您可以使用 将其重定向到一个文件2>$file
,或者您可以将其合并到成功流中2>&1
(在这种情况下,每个 stderr 行都表示为一个[System.Management.Automation.ErrorRecord]
实例)。