Windows PowerShell中SCP文件传输进度获取问题求助
解决PowerShell中scp传输进度实时更新问题
问题分析
你遇到的核心问题是:scp在非交互式终端环境(比如PowerShell脚本中)默认会抑制或缓冲进度输出,导致&操作符无法捕获到实时的进度行。即使重定向了stderr,也因为输出缓冲或终端控制字符的处理,无法从$results中提取进度信息。
解决方案:用.NET Process类实时捕获并解析scp输出
通过直接调用.NET的System.Diagnostics.Process类,可以绕过PowerShell的输出缓冲,实时捕获scp的stderr输出(scp的进度信息默认输出到stderr),然后通过正则表达式提取百分比,更新Write-Progress。
以下是完整的实现脚本:
# 配置参数 $userAtHost = "user@host" $remoteDirectory = "/path/to/remote/files/*" # 可替换为具体文件或目录 $localDirectory = "C:\path\to\local\dir" # 正则表达式匹配scp进度行中的百分比(适配OpenSSH scp的输出格式) $progressRegex = [regex]'(\d+)%' # 创建ProcessStartInfo配置 $psi = New-Object System.Diagnostics.ProcessStartInfo $psi.FileName = "scp.exe" $psi.Arguments = "-v -T ""$userAtHost:$remoteDirectory"" ""$localDirectory""" $psi.RedirectStandardError = $true $psi.RedirectStandardOutput = $true $psi.UseShellExecute = $false $psi.CreateNoWindow = $true # 启动进程 $process = New-Object System.Diagnostics.Process $process.StartInfo = $psi $process.Start() | Out-Null # 实时读取stderr输出,解析进度 while (!$process.HasExited) { $line = $process.StandardError.ReadLine() if ($line) { # 匹配百分比 $match = $progressRegex.Match($line) if ($match.Success) { $percent = [int]$match.Groups[1].Value Write-Progress -Activity "SCP文件传输" -Status "已完成 $percent%" -PercentComplete $percent } # 可选:输出调试信息,查看scp的所有输出 # Write-Host $line } # 短暂休眠,避免占用过高CPU Start-Sleep -Milliseconds 100 } # 处理剩余输出(如果有) while ($line = $process.StandardError.ReadLine()) { $match = $progressRegex.Match($line) if ($match.Success) { $percent = [int]$match.Groups[1].Value Write-Progress -Activity "SCP文件传输" -Status "已完成 $percent%" -PercentComplete $percent } } # 等待进程结束并获取退出码 $process.WaitForExit() $exitCode = $process.ExitCode # 完成后清除进度条 Write-Progress -Activity "SCP文件传输" -Completed -Status "传输完成" # 检查退出码 if ($exitCode -ne 0) { Write-Error "SCP传输失败,退出码: $exitCode" }
关键说明
- scp输出解析:不同版本的scp(比如OpenSSH vs 其他实现)进度输出格式可能略有不同,如果默认的正则表达式不匹配,可以打开脚本中的
Write-Host $line查看输出,调整$progressRegex的匹配规则。 - TTY模拟:此方案不需要额外的TTY模拟工具,通过直接捕获stderr输出就能获取进度,避免了Windows下没有
script命令的问题。 - 性能优化:加入
Start-Sleep -Milliseconds 100减少CPU占用,你可以根据需求调整休眠时间。
内容的提问来源于stack exchange,提问作者Verify
相关产品推荐
相关产品推荐

