2010-02-26 28 views
6

Hãy xem xét các chương trình Perl ngớ ngẩn sau đây:Làm cách nào để kết hợp các đối số dòng lệnh và tên tệp cho <> trong Perl?

$firstarg = $ARGV[0]; 

print $firstarg; 

$input = <>; 

print $input; 

tôi chạy nó từ một thiết bị đầu cuối như:

perl myprog.pl sample_argument 

Và nhận được lỗi này:

Can't open sample_argument: No such file or directory at myprog.pl line 5. 

Bất cứ ý tưởng tại sao điều này là gì? Khi nó được chuyển đến <> là nó đang cố đọc từ tệp (không tồn tại), "sample_argument" hay gì đó? Và tại sao?

Trả lời

12

<> là viết tắt cho "đọc từ các tập tin quy định tại @ARGV, hoặc nếu @ARGV là trống rỗng, sau đó đọc từ STDIN". Trong chương trình của bạn, @ARGV chứa giá trị ("sample_argument") và do đó Perl cố đọc từ tệp đó khi bạn sử dụng toán tử <>.

Bạn có thể sửa chữa nó bằng cách xóa @ARGV trước khi bạn nhận được để các <> dòng:

$firstarg = shift @ARGV; 
print $firstarg; 
$input = <>;  # now @ARGV is empty, so read from STDIN 
print $input; 
+2

Aha! Thay đổi nó thành đã hoạt động tốt :) – Jimmeh

1

Theo mặc định, perl tiêu thụ đối số dòng lệnh dưới dạng tệp đầu vào cho <>. Sau khi bạn đã sử dụng chúng, bạn nên tiêu thụ chúng mình với shift;

+0

Bạn có nó ngược. Perl không làm bất cứ điều gì với '@ ARGV' theo mặc định. Đó là hành vi của '<>' đó là đặc biệt. –

+0

Đó là điều tôi đang nói. Điều đó <> sử dụng @ARGV trừ khi bạn tiêu thụ chúng với sự thay đổi. –

8

Xem man page perlio, mà đọc trong phần:

The null filehandle <> is special: it can be used to emulate the behavior of sed and awk. Input from <> comes either from standard input, or from each file listed on the command line. Here’s how it works: the first time <> is evaluated, the @ARGV array is checked, and if it is empty, $ARGV[0] is set to "-", which when opened gives you standard input. The @ARGV array is then processed as a list of filenames.

Nếu bạn muốn STDIN, sử dụng STDIN, không phải là <>.

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