Bagaimana cara terbaik (secara idiomatis) untuk gagal skrip perl (dijalankan dengan -n / -p) ketika file input tidak ditemukan?

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

Saya benar-benar ingin skrip perl gagal saat file tidak ada. Apa cara "tepat" untuk membuat -p atau -n gagal ketika file input tidak ada?

William Pursell
sumber

Jawaban:

6

The beralih p hanya jalan pintas untuk membungkus kode Anda (argumen berikut -e) dalam lingkaran ini:

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

(-n adalah sama tetapi tanpa melanjutkan blok.)

The <>Operator kosong setara dengan readline *ARGV, dan yang terbuka setiap argumen dalam suksesi sebagai file untuk membaca dari. Tidak ada cara untuk memengaruhi penanganan kesalahan dari implisit yang terbuka, tetapi Anda dapat membuat peringatan yang dipancarkannya fatal (catatan, ini juga akan memengaruhi beberapa peringatan terkait dengan -i switch):

perl -Mwarnings=FATAL,inplace -pe 1 foo && echo ok
Grinnz
sumber
@MarkReed inplace adalah kategori peringatan yang menarik bagi kami. Tidak ada alasan untuk memengaruhi peringatan lainnya.
Grinnz
Dari peringatan :The presence of the word "FATAL" in the category list will escalate warnings in those categories into fatal errors in that lexical scope.
Grinnz
Benar, inplacekategorinya; tanpanya, -Mwarnings=FATALberarti FATAL => all, yang tidak kita inginkan. oke.
Mark Reed
4

Atur bendera di badan loop, periksa bendera di blok END di akhir oneliner.

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

Perhatikan bahwa itu hanya gagal ketika tidak ada file yang diproses.

Untuk melaporkan masalah ketika tidak semua file ditemukan, Anda dapat menggunakan sesuatu seperti

perl -pe 'BEGIN{ $files = @ARGV} $found++ if eof; ... ;END {die "Some files not found" unless $files == $found}'
choroba
sumber
1
Jika skrip Anda seharusnya mengambil file sebagai argumen daripada membaca dari stdin, alternatif yang lebih ringan untuk solusi ini adalah BEGIN{die "File not found" unless -f $ARGV[0]}. (Saya katakan lebih ringan, karena tidak melibatkan pengaturan bendera dan menambahkan 2 buah kode)
Dada
Juga mengasumsikan semua file memiliki panjang non-nol.
Tanktalus