2010-05-23 33 views
7

Các mã sau đây được làm việc loại tốt:Làm cách nào để lấy kết quả đầu ra từ ống Perl khi nó có sẵn?

open(PIPE, '-|', 'ant'); 
for(<PIPE>) { 
    print; 
} 

Tuy nhiên, nó không làm những gì tôi muốn. Kể từ khi xây dựng Ant có thể mất 5 phút, tôi muốn xem dòng đầu ra của dòng. Thay vào đó, tôi nhận được toàn bộ đầu vào ở cuối quá trình.

Nhìn vào nó bằng trình gỡ lỗi Perl, Perl đợi câu lệnh 'for', cho đến khi Ant kết thúc. Tại sao vậy?

Trả lời

8

Chỉ cần cho đầy đủ (vấn đề đã được giải quyết như đã chỉ ra trong các bình luận cho câu trả lời Uri của) các vấn đề nảy sinh vì biểu thức for đánh giá <> điều hành trong danh sách ngữ cảnh (see), tương đương như sau:

foreach $line (@lines = <PIPE>) { 
    print $line; 
} 

Trong ngữ cảnh danh sách, toán tử <> cố gắng đọc tất cả dòng từ đầu vào của nó để asign vào danh sách - và đầu vào đến từ một quá trình, nó sẽ chặn cho đến khi quá trình kết thúc. Chỉ sau đó nó sẽ nhập vào vòng lặp.

Cú pháp thay thế

while(<PIPE>) {   
    print; 
} 

tương đương thay vào đó

while( $line = <PIPE>) { 
    print $line; 
} 

tức là, nó tiêu thụ mỗi dòng từ đầu vào trong mỗi vòng lặp, và đây là những gì người ta muốn làm gì trong tình huống này .

3

Tôi tin rằng sự cố đang được lưu vào bộ đệm. Bạn có thể làm cho filehandle nóng (không có bộ đệm) như sau:

select PIPE; 
$| = 1; # the pipe is just a coincidence. that's the variable's name 
select STDOUT; # select it back 

này nên vô hiệu hóa đệm cho PIPE. Tôi đã đọc về một cái gì đó như thế này trong Học Perl, 5TH. Xem thêm this. Bạn có lẽ cũng nên chắc chắn rằng bộ đệm không xảy ra ở đâu đó khác.

EDIT: OP đăng rằng thay thế cho với khi giải quyết vấn đề

Tôi nghĩ rằng tôi hiểu bây giờ. while lấy mỗi dòng và chạy vòng lặp, trong khi for hoạt động như foreachtrước tiên nhận tất cả các dòng (cần có ngữ cảnh danh sách) và rồi lặp qua các dòng.

+7

Đệm có thể là vấn đề, nhưng bộ đệm có vấn đề nằm ở phía Ant, không phải của Perl. Bạn chỉ cần tắt đệm trên đường ống đầu ra, không phải đường ống đầu vào.Bạn sẽ cần phải tìm cách nào đó để báo cho Ant không được đệm đầu ra của nó. Bạn không thể khắc phục sự cố ở phía bên Perl. – cjm

2

Tìm thấy. Vấn đề là với câu lệnh 'for'.

Các mã sau đây làm việc như mong đợi

open(PIPE, '-|', 'ant'); 
while(<PIPE>) {   # replacing 'for' with 'while' 
    print; 
} 

Tôi không biết lý do, nhưng bây giờ nó đang làm việc.

+2

Để hiểu lý do, hãy xem http://stackoverflow.com/questions/585341/ – Joe

+0

Nếu bạn trả lời bạn sở hữu câu hỏi, bạn nên chỉnh sửa câu hỏi gốc và thêm câu trả lời thay vì đăng trả lời. –

+2

@Barry Brown đăng câu trả lời của riêng bạn và chấp nhận nó nếu không có ai cung cấp câu trả lời tốt hơn được chấp nhận (heh) thực hành trên SO. http://meta.stackexchange.com/questions/12513/stackoverflow-should-i-answer-my-own-question-or-not – hobbs

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