2010-03-10 32 views
23

Tôi gặp sự cố với chức năng system. Tôi muốn lưu trữ đầu ra của hàm hệ thống thành một biến.Làm thế nào tôi có thể lưu trữ đầu ra chức năng hệ thống của Perl thành một biến?

Ví dụ,

system("ls"); 

Ở đây tôi muốn tất cả các tên tập tin trong thư mục hiện hành để lưu trữ trong một biến. Tôi biết rằng tôi có thể làm điều này bằng cách chuyển hướng đầu ra vào một tập tin và đọc từ đó và lưu nó vào một biến. Nhưng tôi muốn một cách hiệu quả hơn thế. Không có cách nào khác ư .

+1

sử dụng '$ output = tôi qx (ls 2> &1); 'phần cuối cùng là để nắm bắt cả stdout và stderr –

Trả lời

16

Không, bạn không thể lưu trữ các giá trị của đầu ra ls, kể từ khi hệ thống luôn luôn thực hiện lệnh như một quá trình con, vì vậy hãy thử với backtick 'command` mà thực hiện các lệnh trong hiện tại quá trình riêng của mình!

+4

@abubacker -. Backticks không thực hiện một –

+5

Backticks thực hiện lệnh trong một tiến trình con và nắm bắt đầu ra của nó.Nếu bạn muốn thực hiện lệnh trong cùng một tiến trình, bạn sử dụng 'exec' - nhưng nó sẽ không bao giờ trở lại vì mã Perl ban đầu không còn chạy sau chuyển quá trình sang lệnh khác –

+0

Làm thế nào một người có thể nắm bắt đầu ra của lệnh vào một biến mà không hiển thị nó trên màn hình? – antred

12

Cách đơn giản nhất sử dụng backticks hoặc qx():

my $value = qx(ls); 
print $value; 

Kết quả cũng tương tự như ls.

+1

'echo' i s một lệnh shell, tương đương Perl được gọi là 'print' và' say'. – daxim

+0

Điều đó làm việc cho ls, nhưng không phải cho lệnh find, cho rằng tôi đoán backticks của nó, http://stackoverflow.com/questions/3854651/how-can-i-store-the-result-of-a-system- lệnh-in-a-perl-variable. –

10

Câu trả lời của tôi không giải quyết được sự cố của bạn. Tuy nhiên, nếu bạn thực sự muốn làm danh sách thư mục, đừng gọi hệ thống ls như thế. Sử dụng opendir(), readdir() hoặc vòng lặp while.

Ví dụ,

while (<*>){ 
    print $_ ."\n"; 
} 

Trong thực tế, nếu nó không phải là một chương trình độc quyền của bên thứ ba, luôn luôn cố gắng để chức năng của người sử dụng Perl.

7

Các tài liệu Perl chính thức cho các built-in system bang chức năng:

Đây không phải là những gì bạn muốn sử dụng để chụp đầu ra từ một lệnh, cho rằng bạn nên sử dụng chỉ đơn thuần backticks hoặc qx //, như được mô tả trong "STRING" trong perlop.

Có rất nhiều cách để dễ dàng truy cập vào các tài liệu:

  1. Tại dòng lệnh: perldoc -f system
  2. trực tuyến tại perldoc.perl.org.
  3. Tìm kiếm trên web bằng google.

Nếu bạn muốn mỗi danh sách thư mục lưu trữ vào một phần tử mảng riêng biệt, sử dụng:

my @entries = qx(ls); 
9

Như abubacker nói, bạn có thể sử dụng backticks để bắt đầu ra của một chương trình vào một biến để sử dụng sau.Tuy nhiên, nếu bạn cũng cần phải kiểm tra cho các giá trị trở lại đặc biệt, hoặc bỏ qua cách gọi vỏ, đó là thời gian để mang lại một mô-đun CPAN, IPC::System::Simple:

use IPC::System::Simple qw(capture); 

# Capture output into $result and throw exception on failure 
my $result = capture("some_command"); 

Module này có thể được gọi theo nhiều cách khác nhau, và cho phép bạn tùy chỉnh các giá trị trả về lỗi nào là "chấp nhận được", có nên bỏ qua vỏ hay không, và cách xử lý nhóm các đối số. Nó cũng cung cấp một thay thế thả cho system() mà thêm nhiều kiểm tra lỗi hơn.

0

Một cách nhanh chóng và đơn giản để làm điều này là sử dụng qx() đặc biệt ví dụ của bạn:

my $output = qx(ls 2>&1);

Các 2>&1 phần là để nắm bắt cả stdout và stderr.

2

Sử dụng backticks để lưu trữ đầu ra trong một biến

$output = `ls`; 
+0

Vâng, thông tin này đã được đưa ra trong các câu trả lời khác. – fancyPants

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