2011-12-05 25 views
7

Giả sử tôi muốn chạy một chương trình bên ngoài từ kịch bản của tôi với backticks và đồng thời tôi muốn chụp cả STDOUT và STDERR nhưng trong hai biến khác nhau . Làm thế nào tôi có thể làm điều đó? Đối với istance nếu tôi chạy tập lệnh này ...Cách chụp cả hai STDOUT và STDERR trong hai biến khác nhau bằng cách sử dụng Backticks trong Perl

my $cmd = `snmpwalk -v $version -c $community $hostname $oid`; 

... nếu không có lỗi, mọi thứ hoạt động tốt NHƯNG nếu lệnh nêu lỗi này sẽ được in trên dòng lệnh và tôi không muốn điều đó xảy ra. Tôi cũng muốn ghi lại lỗi. Không có gì phải được in trên màn hình. Bất kỳ ý tưởng?

+2

Bạn có thể muốn có một cái nhìn tại [Net -SNMP] (http://search.cpan.org/~dtown/Net-SNMP-v6.0.1/). Với điều đó bạn sẽ có toàn quyền kiểm soát lỗi và không cần phải lo lắng về việc chuyển hướng đầu ra ở đâu đó khác. –

Trả lời

5

Trong Perl FAQ bạn có các tùy chọn khác nhau tùy thuộc làm thế nào để bạn muốn tiếp tục:

http://perldoc.perl.org/perlfaq8.html#How-can-I-capture-STDERR-from-an-external-command%3f

+0

* Backticks và open() chỉ đọc STDOUT của lệnh. * Vì vậy, có vẻ như tôi không thể chụp STDERR, tôi phải sử dụng Open3, cảm ơn – raz3r

+1

trong khi faq này là đúng, nó là unnec tinh vi phức tạp và IMO chưa hoàn chỉnh. Trong khi ngôn ngữ Perl cơ bản làm cho điều này trở nên khó khăn, có các mô-đun có thể giúp đỡ, xem câu trả lời của tôi cho các ví dụ sử dụng ['Capture :: Tiny'] (http://p3rl.org/Capture::Tiny) –

8

Cách duy nhất để làm điều này với backticks là để chuyển hướng đến một tập tin bên trong lệnh shell:

my $cmd = `snmpwalk -v $version -c $community $hostname $oid 2>error.dat`; 

Nếu bạn muốn chụp các thiết bị lỗi chuẩn bên trong kịch bản của bạn, bạn cần IPC::Open3 thay vì backticks

+0

Tôi không phải xử lý lỗi (vì chúng giống như cảnh báo với tôi) để giải pháp có thể phù hợp với tôi. Tôi sẽ thử ngay bây giờ :) – raz3r

+0

Nó không hoạt động: (error.dat trống và lỗi vẫn được nâng lên trên dòng lệnh :( – raz3r

+1

Tôi không biết tại sao nó không hoạt động. Nếu nó tạo tệp Tôi chỉ có thể giả sử rằng snmpwalk xuất ra lỗi bởi một số cơ chế khác hơn là in trên STDERR, nhưng tôi không biết cái gì. Tôi sẽ nói, nếu bạn không muốn đầu ra anyway, '2>/dev/null', nhưng nếu trường hợp error.dat không hoạt động, cũng không phải vậy, có lẽ là –

11

Bạn không cần phải đi hết đường tới open3, mà IIRC chỉ dành cho thời điểm bạn cần đọc và ghi vào lệnh bên ngoài và thậm chí có các phương pháp khác.

Đối với vấn đề của bạn, tôi đề xuất sử dụng Capture::Tiny, có thể chụp (hoặc thậm chí là tee) STDOUT và STDERR từ bất kỳ thứ gì chạy bên trong khối của nó. Ví dụ, mỗi câu hỏi của bạn:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Capture::Tiny qw/capture/; 

... 

my ($stdout, $stderr) = capture { 
    system ("snmpwalk -v $version -c $community $hostname $oid"); 
}; 

Ví dụ khác xem xét đang hoạt động này:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Capture::Tiny qw/capture/; 

my ($stdout, $stderr) = capture { 
    system ("echo 'hello'"); 
    system ("date"); 
    warn "Arg1!"; 
}; 

print "STDOUT:\n$stdout"; 
print "STDERR:\n$stderr"; 

mà chỉ đưa cho tôi:

STDOUT: 
hello 
Mon Dec 19 23:59:06 CST 2011 
STDERR: 
Arg1! at ./test.pl line 11. 
Các vấn đề liên quan