ฉันจะส่งผ่านอาร์กิวเมนต์บรรทัดคำสั่งไปยังโปรแกรม Perl ได้อย่างไร


137

ฉันกำลังทำงานกับสคริปต์ Perl ฉันจะส่งพารามิเตอร์บรรทัดคำสั่งไปที่มันได้อย่างไร

ตัวอย่าง:

script.pl "string1" "string2"

3
ก่อนอื่นคุณจะต้องให้มันเป็นอย่างนั้น./script.plหรือจะไม่มีอะไรเกิดขึ้นทั้งหมด
คู่ปรับ Shot

คำตอบ:


189

ขึ้นอยู่กับสิ่งที่คุณต้องการจะทำ หากคุณต้องการใช้สองอาร์กิวเมนต์เป็นไฟล์อินพุตคุณสามารถส่งผ่านอาร์กิวเมนต์เหล่านั้นจากนั้นใช้<>เพื่ออ่านเนื้อหา

หากพวกเขามีความหมายที่แตกต่างกันคุณสามารถใช้GetOpt::StdและGetOpt::Longประมวลผลได้อย่างง่ายดาย GetOpt::Stdรองรับสวิตช์ตัวเดียวเท่านั้นและGetOpt::Longมีความยืดหยุ่นมากกว่า จาก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

หรือ@ARGVเป็นตัวแปรพิเศษที่มีอาร์กิวเมนต์บรรทัดคำสั่งทั้งหมด $ARGV[0]เป็นครั้งแรก (เช่น"string1"ในกรณีของคุณ) และ$ARGV[1]เป็นอาร์กิวเมนต์ที่สอง @ARGVคุณไม่จำเป็นต้องโมดูลพิเศษในการเข้าถึง


29
$ ARGV [0] เป็นอาร์กิวเมนต์แรก perl นับจาก 0 และชื่อโปรแกรมอยู่ใน $ 0 ไม่ใช่ @ARGV
Derobert

4
แม้จะมีความสับสน $ ARGV [0] .. นี่เป็นคำตอบที่ฉันหวังว่าจะได้พบเมื่อฉันค้นหาดังนั้นขอบคุณและ +1 จากฉัน
lexu


60

@ARGVคุณจะผ่านพวกเขาในเช่นเดียวกับคุณความคิดกำลังและในสคริปต์ของคุณคุณจะได้รับพวกเขาจากอาร์เรย์ ชอบมาก

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

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

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

}

จากที่นี่


8
นอกจากนี้ยังเป็นที่น่าสังเกตว่าในบางภาษาการเขียนโปรแกรมอาร์กิวเมนต์แรก (0) คือคำสั่งหรือสคริปต์เอง ... ไม่ใช่ในภาษา Perl
danieltalsky

10
แทนที่จะ$#ARGV + 1พูดอย่างนั้นก็ได้@ARGV
Leon Timmermans

1
เพียงแค่ใช้ARGV[0]หรือ$argv[1]หากคุณกำลังมองหาข้อโต้แย้งโดยเฉพาะ
Manoj

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

จะพิมพ์แต่ละอาร์กิวเมนต์


หากไม่ได้ใช้ getopts นี่คือวิธีที่ฉันจะแนะนำรายการการโต้แย้งแบบไม่ทำลายล้าง จากperlmeme.org/howtos/syntax/foreach.htmlดูเหมือนว่าไวยากรณ์นั้นถูกต้อง สำหรับข้อแม้ให้ตรวจสอบส่วนผลข้างเคียง: ตัวแปรควบคุมเป็นนามแฝงขององค์ประกอบรายการ
jaredor

24

อีกวิธีหนึ่งคือทางที่ผิดทางเพศ .....

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

"ถือว่า" มีการส่งสองค่า รหัสพิเศษสามารถตรวจสอบสมมติฐานได้อย่างปลอดภัย


6
ไม่แน่ใจว่านี่เป็นข้อมูลใหม่ แต่ฉันตัดสินใจต่อต้าน downvote เนื่องจากคุณใหม่
Joel Berger

มันไม่ได้เซ็กซี่กว่า ข้อโต้แย้ง@ARGVทั้งหมดสามารถทำได้โดยไม่ต้องดำเนินการใด ๆ จากคุณเช่นเดียวกับ C / C ++ ให้พวกเขาผ่าน argv / argc
Eugen Konkov

21

อีกตัวเลือกหนึ่งคือการใช้ Perl -s เช่น:

#!/usr/bin/perl -s

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

จากนั้นเรียกมันว่าสิ่งนี้:

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

หรือดูบทความต้นฉบับสำหรับรายละเอียดเพิ่มเติม:


13

คุณสามารถเข้าถึงได้โดยตรงโดยการกำหนดตัวแปรพิเศษ@ARGVให้กับรายการของตัวแปร ตัวอย่างเช่น:

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

perl tmp.pl 1 2 3 4 5

ป้อนคำอธิบายรูปภาพที่นี่


7

หากอาร์กิวเมนต์เป็นชื่อไฟล์ที่ต้องอ่านให้ใช้ตัวดำเนินการ diamond (<>) เพื่อรับเนื้อหา:

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

หากอาร์กิวเมนต์เป็นตัวเลือก / สวิตช์ให้ใช้ GetOpt :: Std หรือ GetOpt :: Long ดังที่แสดงโดย slavy13.myopenid.com

ในโอกาสที่พวกเขามีสิ่งอื่นคุณสามารถเข้าถึงได้โดยการเดินผ่าน @ARGV อย่างชัดเจนหรือด้วยshiftคำสั่ง:

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

(โปรดทราบว่าการดำเนินการนี้shiftจะใช้ได้เฉพาะเมื่อคุณอยู่นอกsubs ทั้งหมดภายใน a subมันจะดึงรายการของอาร์กิวเมนต์ที่ส่งไปยังsubมากกว่าที่ส่งผ่านไปยังโปรแกรม)



2

หากคุณต้องการค่าบางอย่างคุณสามารถใช้อาร์เรย์ @ARGV ได้ แต่ถ้าคุณกำลังมองหาบางสิ่งบางอย่างมีประสิทธิภาพมากขึ้นเพื่อที่จะทำบางอย่างในการประมวลผลเลือกบรรทัดคำสั่งคุณควรใช้getopt :: ยาว

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.