Làm cách nào tôi có thể truyền đối số dòng lệnh cho chương trình Perl?


137

Tôi đang làm việc trên một kịch bản Perl. Làm thế nào tôi có thể truyền tham số dòng lệnh cho nó?

Thí dụ:

script.pl "string1" "string2"

3
Chà, trước hết, bạn sẽ cần nó ./script.plhoặc toàn bộ điều không nên xảy ra trong thời gian chạy.
Bắn Parthian

Câu trả lời:


189

Phụ thuộc vào những gì bạn muốn làm. Nếu bạn muốn sử dụng hai đối số làm tệp đầu vào, bạn có thể chuyển chúng vào và sau đó sử dụng <>để đọc nội dung của chúng.

Nếu chúng có ý nghĩa khác nhau, bạn có thể sử dụng GetOpt::StdGetOpt::Longxử lý chúng dễ dàng. GetOpt::Stdchỉ hỗ trợ chuyển đổi một ký tự và GetOpt::Longlinh hoạt hơn nhiều. Từ GetOpt::Long:

use Getopt::Long;
my $data   = "file.dat";
my $length = 24;
my $verbose;
$result = GetOptions ("length=i" => \$length,    # numeric
                    "file=s"   => \$data,      # string
                    "verbose"  => \$verbose);  # flag

Ngoài ra, @ARGVlà một biến đặc biệt có chứa tất cả các đối số dòng lệnh. $ARGV[0]là đối số thứ nhất (nghĩa là "string1"trong trường hợp của bạn) và $ARGV[1]là đối số thứ hai. Bạn không cần một mô-đun đặc biệt để truy cập @ARGV.


29
$ ARGV [0] là đối số đầu tiên; perl tính từ 0 và tên chương trình là $ 0 chứ không phải @ARGV.
derobert

4
bất chấp sự nhầm lẫn $ ARGV [0] .. đây là loại câu trả lời tôi hy vọng tìm thấy, khi tôi tìm kiếm SO, cảm ơn và +1 từ tôi.
lexu


60

Bạn vượt qua chúng giống như bạn đang nghĩ và trong kịch bản của bạn, bạn có được chúng từ mảng @ARGV. Thích như vậy:

my $numArgs = $#ARGV + 1;
print "thanks, you gave me $numArgs command-line arguments.\n";

foreach my $argnum (0 .. $#ARGV) {

   print "$ARGV[$argnum]\n";

}

Từ đây .


8
Cũng đáng lưu ý rằng trong một số ngôn ngữ lập trình, đối số (0) đầu tiên là lệnh hoặc chính kịch bản ... tất nhiên không phải như vậy trong perl.
danieltalsky

10
Thay vì $#ARGV + 1bạn cũng có thể nói@ARGV
Leon Timmermans

1
chỉ sử dụng ARGV[0]hoặc $argv[1]nếu bạn đang tìm kiếm đối số cụ thể.
Manoj

29
foreach my $arg (@ARGV) {
    print $arg, "\n";
}

sẽ in từng đối số.


Nếu không sử dụng getopts, đây là cách tôi khuyên bạn không nên duyệt qua danh sách đối số. Dựa trên perlmeme.org/howtos/syntax/foreach.html có vẻ như cú pháp là chính xác; để biết thêm, hãy kiểm tra phần, Tác dụng phụ: Biến điều khiển là bí danh của thành phần danh sách
jaredor

24

Ngoài ra, một cách perlish quyến rũ hơn .....

my ($src, $dest) = @ARGV;

"Giả sử" hai giá trị được thông qua. Mã bổ sung có thể xác minh giả định là an toàn.


6
Không chắc đây là thông tin mới như thế nào, nhưng tôi đã quyết định chống lại downvote, vì bạn là người mới.
Joel Berger

Nó không quyến rũ hơn. Tất cả các đối số đều có sẵn thông qua @ARGVmà không có bất kỳ hành động nào từ bạn, giống như C / C ++ cung cấp chúng thông qua argv / argc
Eugen Konkov

21

Tuy nhiên, một tùy chọn khác là sử dụng perl -s, ví dụ:

#!/usr/bin/perl -s

print "value of -x: $x\n";
print "value of -name: $name\n";

Sau đó gọi nó như thế này:

% ./myprog -x -name=Jeff
value of -x: 1
value of -name: Jeff

Hoặc xem bài viết gốc để biết thêm chi tiết:


13

Bạn có thể truy cập chúng trực tiếp, bằng cách gán biến đặc biệt @ARGVcho danh sách các biến. Ví dụ:

( $st, $prod, $ar, $file, $chart, $e, $max, $flag ,$id) = @ARGV;

perl tmp.pl 1 2 3 4 5

nhập mô tả hình ảnh ở đây


7

Nếu các đối số là tên tệp được đọc từ đó, hãy sử dụng toán tử kim cương (<>) để lấy nội dung của chúng:

while (my $line = <>) {
  process_line($line);
}

Nếu các đối số là tùy chọn / công tắc, hãy sử dụng GetOpt :: Std hoặc GetOpt :: Long, như đã được hiển thị bởi sleef13.myopenid.com.

Nếu bạn là người khác, bạn có thể truy cập chúng bằng cách truy cập @ARGV một cách rõ ràng hoặc bằng shiftlệnh:

while (my $arg = shift) {
  print "Found argument $arg\n";
}

(Lưu ý rằng làm điều này với shiftsẽ chỉ hoạt động nếu bạn ở bên ngoài tất cả sub. Trong vòng a sub, nó sẽ truy xuất danh sách các đối số được truyền cho subchứ không phải các đối số được truyền cho chương trình.)



2

Nếu bạn chỉ muốn một số giá trị, bạn chỉ có thể sử dụng mảng @ARGV. Nhưng nếu bạn đang tìm kiếm thứ gì đó mạnh hơn để xử lý một số tùy chọn dòng lệnh, bạn nên sử dụng Getopt :: Long .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.