2014-12-12 7 views
6

Attualmente sto scrivendo uno script in Powershell che consente di copiare una cartella in un repository SVN in un'altra mentre conserva la cronologia. Un esempio di tale comando è:Le tubazioni Powershell causano l'uso di memoria esplosiva

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

Questo provoca un uso molto elevato di memoria in Powershell. Sembra che Powershell prima esegua svnadmin.exe e bufferizza lo stdout dall'amministratore SVN, quindi esegue svndumpfilter e i buffer che emettono ed infine esegue svnadmin.exe.

posso lavorare intorno ad esso con la creazione di un file batch separato:

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

e quindi chiamando da PowerShell:

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

Ma questa sembra una soluzione brutta e inutile.

C'è un modo per dire a Powershell di passare direttamente durante la piping invece del buffering?

+0

Prova 'svnadmin.exe ... | out-string | svnfilter.exe ... '? Questo potrebbe convincere PowerShell a convogliare ogni linea invece di raccogliere tutto. Non ho SVN né lo so, quindi scuse se questo si rompe orribilmente. – Eris

risposta

2

Non è l'output in fase di buffering, ma piuttosto l'input per qualsiasi processo esterno. È possibile verificare il comportamento con una funzione come questa:

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

Se quindi si esegue:

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

Vedrai uscita del LongRunning.exe in verbose ma Other.exe non sarà eseguito fino a quando la sua pipeline è chiusa. Se si esegue questa operazione:

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

Vedrete alternando linee di output dettagliato/Console senza buffer perché gli ingressi non stanno attraversando i limiti del processo.

Niente di tutto ciò ti aiuta davvero. Si potrebbe aggirare questo problema ricadendo su .NET per avviare i processi e copiare manualmente STDOUT su STDIN [1], ma è molto lavoro per una piccola ricompensa. La cosa più semplice da fare sarebbe passare i comandi al CMD, qualcosa come:

& 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

+0

Grazie, è più o meno quello che temevo. Cosa fa "| ^" nel tuo esempio? – Sebazzz

+0

^| sfugge al | carattere, che è necessario perché è passato come parametro a cmd.exe. http://ss64.com/nt/syntax-esc.html – tby

Problemi correlati