You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 13:36:04