Jak najlepiej (idiomatycznie) zawieść skrypt perla (uruchomić z -n / -p), gdy nie znaleziono pliku wejściowego?


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

Naprawdę chciałbym, aby skrypt Perla zawiódł, gdy plik nie istnieje. Jaki jest „właściwy” sposób, aby polecenie -p lub -n nie powiodło się, gdy plik wejściowy nie istnieje?

Odpowiedzi:


6

Przełącznik -p to tylko skrót do owijania swój kod (argument następujący -e) w tej pętli:

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

(-n jest taki sam, ale bez bloku kontynuacji).

<>Operator pusty odpowiada readline *ARGVi który otwiera każdy argument z rzędu w postaci pliku do odczytu z. Nie ma sposobu, aby wpłynąć na obsługę błędów tego niejawnego otwarcia, ale można ustawić ostrzeżenie, które emituje błąd (uwaga, wpłynie to również na kilka ostrzeżeń związanych z przełącznikiem -i):

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

@ MarkReed inplace to interesująca nas kategoria ostrzeżeń. Nie ma powodu, aby wpływać na inne ostrzeżenia.
Grinnz

Z ostrzeżeń :The presence of the word "FATAL" in the category list will escalate warnings in those categories into fatal errors in that lexical scope.
Grinnz

Tak, inplacejest kategoria; bez niego -Mwarnings=FATALoznacza to FATAL => all, czego nie chcemy. Rozumiem.
Mark Reed,

4

Ustaw flagę w treści pętli, zaznacz flagę w bloku END na końcu onelinera.

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

Pamiętaj, że kończy się niepowodzeniem tylko wtedy, gdy żaden plik nie został przetworzony.

Aby zgłosić problem, gdy nie wszystkie pliki zostały znalezione, możesz użyć czegoś takiego

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

1
Jeśli twój skrypt ma pobierać pliki jako argumenty, a nie czytać ze standardowego wejścia, byłaby lżejsza alternatywa dla tego rozwiązania BEGIN{die "File not found" unless -f $ARGV[0]}. (Mówię lżejsze, ponieważ nie wymaga to ustawiania flagi i dodawania 2 kodów)
Dada

Zakłada również, że wszystkie pliki mają niezerową długość.
Tanktalus,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.