วิธีที่ดีที่สุด (ตามลำดับ) ที่จะล้มเหลวสคริปต์ Perl (ทำงานด้วย -n / -p) เมื่อไม่พบไฟล์อินพุต?


11
$ perl -pe 1 foo && echo ok
Can't open foo: No such file or directory.
ok

ฉันต้องการให้สคริปต์ perl ล้มเหลวเมื่อไม่มีไฟล์อยู่ วิธี "เหมาะสม" ในการทำให้ -p หรือ -n ล้มเหลวเมื่อไม่มีไฟล์อินพุตอยู่

คำตอบ:


6

สวิทช์ -pเป็นเพียงทางลัดสำหรับการตัดรหัสของคุณ (อาร์กิวเมนต์ต่อไปนี้อี) ในวงนี้:

LINE:
  while (<>) {
      ...             # your program goes here
  } continue {
      print or die "-p destination: $!\n";
  }

(-n เหมือนกัน แต่ไม่มีบล็อกต่อไป)

ตัว<>ดำเนินการว่างเท่ากับreadline *ARGVและเปิดแต่ละอาร์กิวเมนต์อย่างต่อเนื่องเป็นไฟล์ที่จะอ่าน ไม่มีวิธีใดที่จะมีอิทธิพลต่อการจัดการข้อผิดพลาดของการเปิดโดยปริยายนั้น แต่คุณสามารถเตือนได้ว่าปล่อยออกมาอย่างรุนแรง (หมายเหตุสิ่งนี้จะส่งผลต่อคำเตือนหลายประการที่เกี่ยวข้องกับสวิตช์ -i):

perl -Mwarnings=FATAL,inplace -pe 1 foo && echo ok

@MarkReed inplace เป็นหมวดหมู่คำเตือนที่เราสนใจไม่มีเหตุผลใดที่จะส่งผลต่อคำเตือนอื่น ๆ
Grinnz

จากคำเตือน :The presence of the word "FATAL" in the category list will escalate warnings in those categories into fatal errors in that lexical scope.
Grinnz

ขวาinplaceคือหมวดหมู่; ก็ไม่มีซึ่ง-Mwarnings=FATALหมายความว่าFATAL => allเราไม่ต้องการ เข้าใจแล้ว
Mark Reed

4

ตั้งค่าสถานะในส่วนของวนรอบตรวจสอบค่าสถานะในบล็อก END ที่ส่วนท้ายของ oneliner

perl -pe '$found = 1; ... ;END {die "No file found" unless $found}' -- file1 file2

โปรดทราบว่ามันจะล้มเหลวเมื่อไม่มีการประมวลผลไฟล์

ในการรายงานปัญหาเมื่อไม่พบไฟล์ทั้งหมดคุณสามารถใช้สิ่งที่ต้องการ

perl -pe 'BEGIN{ $files = @ARGV} $found++ if eof; ... ;END {die "Some files not found" unless $files == $found}'

1
หากสคริปต์ของคุณควรใช้ไฟล์เป็นอาร์กิวเมนต์แทนที่จะอ่านจาก stdin จะเป็นทางเลือกที่เบากว่าสำหรับโซลูชันBEGIN{die "File not found" unless -f $ARGV[0]}นี้ (ฉันบอกว่าเบาเพราะมันไม่ได้เกี่ยวข้องกับการตั้งค่าสถานะและเพิ่มรหัส 2 ชิ้น)
Dada

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