【发布时间】:2017-07-21 01:56:40
【问题描述】:
在相当受限的环境中,如果我想自动执行某些任务,我基本上只能使用 Powershell + Plink。
我想创建一个函数:
- 如果需要,在输出到达时显示输出
- 捕获所有输出(stdout 和 stderr),以便以后进一步解析或记录到控制台/文件/任何内容
- 自动输入密码
不幸的是,在我输入密码输出捕获停止的行之后。当我只捕获标准输出时,它曾经工作过。在捕获了 stderr 之后,就没有更多的运气了。
代码:
function BaseRun {
param ($command, $arguments, $output = "Console")
$procInfo = New-Object System.Diagnostics.ProcessStartInfo
$procInfo.RedirectStandardOutput = $true
$procInfo.RedirectStandardError = $true
$procInfo.RedirectStandardInput = $true
$procInfo.FileName = $command
$procInfo.Arguments = $arguments
$procInfo.UseShellExecute = $false
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $procInfo
[void]$process.Start()
$outputStream = $process.StandardOutput
$errorStream = $process.StandardError
$inputStream = $process.StandardInput
$outputBuffer = New-Object System.Text.StringBuilder
Start-Sleep -m 2000
$inputStream.Write("${env:password}`n")
while (-not $process.HasExited) {
do {
$outputLine = $outputStream.ReadLine()
$errorLine = $errorStream.ReadLine()
[void]$outputBuffer.Append("$outputLine`n")
if (($output -eq "All") -or ($output -eq "Console")) {
Write-Host "$outputLine"
Write-Host "$errorLine"
}
} while (($outputLine -ne $null) -and ($errorLine -ne $null))
}
return $outputBuffer.ToString()
}
【问题讨论】:
-
我没有现成的解决方案,但 IIRC 问题是由您同步执行的事实引起的。所以我认为你需要将
$inputStream.Write移动到一个新线程/RunSpace/whatever 中。或者通过Register-ObjectEvent $Process OutputDataReceived ......进行输出收集 -
该死,我希望我能避免整个异步shebang。
标签: powershell process stdout stderr plink