Bagaimana saya bisa meneruskan argumen baris perintah ke program Perl?

137

Saya sedang mengerjakan skrip Perl. Bagaimana saya bisa meneruskan parameter baris perintah ke sana?

Contoh:

script.pl "string1" "string2"
lamcro
sumber
3
Yah, pertama-tama, Anda akan perlu untuk menjadi ./script.platau keseluruhan lotta nothin 'akan terjadi runtime.
Parthian Shot

Jawaban:

189

Tergantung pada apa yang ingin Anda lakukan. Jika Anda ingin menggunakan dua argumen sebagai file input, Anda bisa meneruskannya dan kemudian gunakan <>untuk membaca kontennya.

Jika mereka memiliki arti yang berbeda, Anda dapat menggunakan GetOpt::Stddan GetOpt::Longmemprosesnya dengan mudah. GetOpt::Stdhanya mendukung sakelar satu karakter dan GetOpt::Longjauh lebih fleksibel. Dari 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

Atau, @ARGVadalah variabel khusus yang berisi semua argumen baris perintah. $ARGV[0]adalah argumen pertama (mis. "string1"dalam kasus Anda) dan $ARGV[1]argumen kedua. Anda tidak perlu modul khusus untuk mengakses @ARGV.

pengguna44511
sumber
29
$ ARGV [0] adalah argumen pertama; perl dihitung dari 0, dan nama program dalam $ 0 bukan @ARGV.
derobert
4
meskipun kebingungan $ ARGV [0] .. ini adalah jenis jawaban yang saya harap temukan, ketika saya mencari SO, terima kasih dan +1 dari saya.
lexu
60

Anda meneruskannya persis seperti yang Anda pikirkan, dan dalam skrip Anda, Anda mendapatkannya dari array @ARGV. Seperti itu:

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

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

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

}

Dari sini .

George Stocker
sumber
8
Ini juga perlu dicatat bahwa dalam beberapa bahasa pemrograman argumen (0) pertama adalah perintah atau skrip itu sendiri ... tentu saja tidak demikian dalam perl.
danieltalsky
10
Alih-alih $#ARGV + 1Anda juga bisa mengatakan@ARGV
Leon Timmermans
1
gunakan saja ARGV[0]atau $argv[1]jika Anda mencari argumen tertentu.
Manoj
29
foreach my $arg (@ARGV) {
    print $arg, "\n";
}

akan mencetak setiap argumen.

nrich
sumber
Jika tidak menggunakan getopts, ini adalah bagaimana saya akan merekomendasikan non-destruktif melintasi daftar argumen. Berdasarkan perlmeme.org/howtos/syntax/foreach.html sepertinya sintaksinya benar; untuk peringatan, periksa bagian, Efek samping: Variabel kontrol adalah alias ke elemen daftar
jaredor
24

Atau, cara perlish yang lebih seksi .....

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

"Asumsikan" dua nilai dilewatkan. Kode tambahan dapat memverifikasi anggapannya aman.

rastin71
sumber
6
Tidak yakin bagaimana ini info baru, tetapi saya memutuskan untuk tidak downvote, karena Anda baru.
Joel Berger
Itu tidak seksi. Semua argumen tersedia melalui @ARGVtanpa tindakan dari Anda seperti C / C ++ menyediakannya melalui argv / argc
Eugen Konkov
21

Namun pilihan lain adalah menggunakan perl -s, mis:

#!/usr/bin/perl -s

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

Kemudian panggil seperti ini:

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

Atau lihat artikel asli untuk lebih jelasnya:

Joao Costa
sumber
13

Anda dapat mengaksesnya secara langsung, dengan menetapkan variabel khusus @ARGVke daftar variabel. Jadi, misalnya:

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

perl tmp.pl 1 2 3 4 5

masukkan deskripsi gambar di sini

pkm
sumber
7

Jika argumen adalah nama file yang bisa dibaca, gunakan operator berlian (<>) untuk mendapatkan isinya:

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

Jika argumennya adalah opsi / switch, gunakan GetOpt :: Std atau GetOpt :: Long, seperti yang sudah ditunjukkan oleh slavy13.myopenid.com.

Jika itu sesuatu yang lain, Anda dapat mengaksesnya dengan berjalan melalui @ARGV secara eksplisit atau dengan shiftperintah:

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

(Perhatikan bahwa melakukan ini dengan shifthanya akan berfungsi jika Anda berada di luar semua sub. Dalam a sub, ia akan mengambil daftar argumen yang diteruskan kesub bukan diteruskan ke program.)

Dave Sherohman
sumber
5
my $output_file;

if((scalar (@ARGV) == 2) && ($ARGV[0] eq "-i"))

{

$output_file= chomp($ARGV[1]) ;


}
pengguna3331697
sumber
2

Jika Anda hanya ingin beberapa nilai, Anda bisa menggunakan array @ARGV. Tetapi jika Anda mencari sesuatu yang lebih kuat untuk melakukan pemrosesan opsi baris perintah, Anda harus menggunakan Getopt :: Long .

Marc
sumber