2014-12-12 13 views
6

Tôi hiện đang viết một tập lệnh trong Powershell cho phép sao chép một thư mục trong kho SVN sang kho khác trong khi vẫn giữ lại lịch sử. Ví dụ về lệnh như vậy là:Đường ống Powershell gây ra việc sử dụng bộ nhớ bùng nổ

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

Điều này gây ra việc sử dụng bộ nhớ rất cao trong Powershell. Nó xuất hiện rằng Powershell đầu tiên thực hiện svnadmin.exe và bộ đệm stdout từ SVN admin, sau đó thực hiện svndumpfilter và bộ đệm mà đầu ra và cuối cùng thực hiện svnadmin.exe.

tôi có thể làm việc xung quanh nó bằng cách tạo ra một tập tin thực thi riêng biệt:

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

Và sau đó gọi nó từ Powershell:

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

Nhưng điều này cảm thấy như một cách giải quyết khó chịu và không cần thiết.

Có cách nào để yêu cầu Powershell truyền trực tiếp khi đường ống thay vì đệm không?

+0

Hãy thử 'svnadmin.exe ... | out-string | svnfilter.exe ... '? Điều này có thể thuyết phục powershell để ống mỗi dòng thay vì thu thập tất cả mọi thứ. Tôi không có SVN cũng không biết, vì vậy xin lỗi nếu điều này phá vỡ khủng khiếp. – Eris

Trả lời

2

Nó không phải là đầu ra được đệm, mà là đầu vào cho bất kỳ quá trình bên ngoài. Bạn có thể xác minh hành vi với một chức năng như thế này:

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

Nếu bạn sau đó chạy:

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

Bạn sẽ thấy đầu ra của LongRunning.exe trong Verbose nhưng Other.exe sẽ không được chạy cho đến khi đường ống của nó bị đóng. Nếu bạn làm điều này:

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

Bạn sẽ thấy xen kẽ các dòng đầu ra Verbose/Console không có đệm vì đầu vào không vượt qua ranh giới quy trình.

Không điều nào thực sự hữu ích cho bạn. Bạn có thể làm việc xung quanh điều này bằng cách quay trở lại .NET để khởi chạy các tiến trình và sao chép thủ công STDOUT thành STDIN [1], nhưng nó có rất nhiều công việc cho phần thưởng nhỏ. Điều đơn giản nhất để làm là vượt qua các lệnh của bạn để CMD, một cái gì đó như:

& 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

Cảm ơn, đó là khá nhiều những gì tôi sợ. "| ^" Làm gì trong ví dụ của bạn? – Sebazzz

+0

^| thoát khỏi | ký tự, đó là cần thiết vì nó được truyền như một tham số đến cmd.exe. http://ss64.com/nt/syntax-esc.html – tby

Các vấn đề liên quan