Qual è il modo migliore (idiomaticamente) di fallire lo script perl (eseguire con -n / -p) quando il file di input non viene trovato?


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

Vorrei davvero che lo script perl fallisse quando il file non esiste. Qual è il modo "corretto" per far fallire -p o -n quando il file di input non esiste?

Risposte:


6

L' opzione -p è solo una scorciatoia per racchiudere il codice (l'argomento che segue -e) in questo ciclo:

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

(-n è lo stesso ma senza il blocco continue.)

L' <>operatore vuoto equivale a readline *ARGV, e questo apre ogni argomento in successione come file da cui leggere. Non c'è modo di influenzare la gestione degli errori di quell'implicito aperto, ma puoi rendere l' avviso che emette fatale (nota, questo influenzerà anche diversi avvisi relativi all'opzione -i):

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

@MarkReed inplace è la categoria di avvisi a cui siamo interessati. Non vi è alcun motivo per influire su altri avvisi.
Grinnz,

Dagli avvertimenti :The presence of the word "FATAL" in the category list will escalate warnings in those categories into fatal errors in that lexical scope.
Grinnz,

Giusto, inplaceè la categoria; senza di essa, -Mwarnings=FATALsignifica FATAL => all, che non vogliamo. fatto.
Mark Reed,

4

Posiziona un flag nel corpo del loop, controlla il flag nel blocco END alla fine del puntale.

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

Si noti che non riesce solo quando nessun file è stato elaborato.

Per segnalare il problema quando non sono stati trovati tutti i file, è possibile utilizzare qualcosa di simile

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

1
Se si suppone che il tuo script prenda file come argomenti piuttosto che letti da stdin, un'alternativa più leggera a questa soluzione sarebbe BEGIN{die "File not found" unless -f $ARGV[0]}. (Dico più leggero, perché non implica l'impostazione di una bandiera e l'aggiunta di 2 pezzi di codici)
Dada,

Presuppone inoltre che tutti i file abbiano una lunghezza diversa da zero.
Tanktalus,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.