【问题标题】:Powershell piping causes explosive memory usagePowershell 管道会导致爆炸性的内存使用
【发布时间】:2015-02-10 23:52:05
【问题描述】:

我目前正在 Powershell 中编写一个脚本,该脚本允许将 SVN 存储库中的文件夹复制到另一个存储库,同时保留历史记录。此类命令的一个示例是:

svnadmin.exe dump $FromRepoPath `
    | svndumpfilter.exe include --drop-empty-revs --renumber-revs --preserve-revprops $Folder `
    | svnadmin.exe load --ignore-uuid $ToRepoPath

这会导致 Powershell 中的内存使用率非常高。看来Powershell首先执行svnadmin.exe并缓冲来自SVN admin的stdout,然后执行svndumpfilter并缓冲输出,最后执行svnadmin.exe。

我可以通过创建一个单独的批处理文件来解决它:

@echo off
svnadmin.exe dump %1 | svndumpfilter.exe include --drop-empty-revs --renumber-revs --preserve-revprops %2 | svnadmin.exe load --ignore-uuid %3

然后从 Powershell 调用它:

cmd.exe /c "SvnHelper.cmd $FromRepoPath $Folder $ToRepoPath"

但这感觉像是一种令人讨厌且不必要的解决方法。

有没有办法告诉Powershell在管道时直接传递而不是缓冲它?

【问题讨论】:

  • 试试svnadmin.exe ... | out-string | svnfilter.exe ...?这可能会说服 powershell 对每一行进行管道传输,而不是收集所有内容。我没有 SVN 也不知道,如果这严重破坏了,请道歉。

标签: powershell batch-file


【解决方案1】:

缓冲的不是输出,而是任何外部进程的输入。您可以使用如下函数验证行为:

function Read-Pipeline {
[cmdletbinding()]
param ([Parameter(Mandatory = $true, ValueFromPipeline=$true)] $inp)
    Begin {}
    Process {Write-Verbose $inp ; Return $inp}
    End {}
}

如果你随后运行:

.\LongRunning.exe | Read-Pipeline -Verbose | .\Other.exe

您会在 Verbose 中看到 LongRunning.exe 的输出,但 Other.exe 在其管道关闭之前不会运行。如果你这样做:

.\LongRunning.exe | Read-Pipeline -Verbose | Write-Host

您将看到交替的 Verbose / Console 输出行,没有缓冲,因为输入没有跨越进程边界。

这些都不能真正帮助你。您可以通过回退到 .NET 来启动进程并手动将 STDOUT 复制到 STDIN [1] 来解决这个问题,但这是很多工作却没有什么回报。最简单的做法是将您的命令传递给 CMD,例如:

& cmd.exe "/C svnadmin.exe dump $FromRepoPath ^| svndumpfilter.exe include --drop-empty-revs --renumber-revs --preserve-revprops $Folder ^| svnadmin.exe load --ignore-uuid $ToRepoPath

[1]http://sushihangover.blogspot.com/2012/01/powershell-piping-standard-output-to.html

【讨论】:

  • 谢谢,这正是我所担心的。 “|^”在您的示例中做了什么?
  • ^|逃脱|字符,这是必需的,因为它作为参数传递给 cmd.exe。 ss64.com/nt/syntax-esc.html
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-12
  • 1970-01-01
相关资源
最近更新 更多