¿Cuál es la mejor manera (idiomáticamente) de fallar el script perl (ejecutar con -n / -p) cuando no se encuentra el archivo de entrada?

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

Realmente me gustaría que el script perl fallara cuando el archivo no existe. ¿Cuál es la forma "correcta" de hacer que -p o -n falle cuando el archivo de entrada no existe?

William Pursell
fuente

Respuestas:

6

El modificador -p es solo un acceso directo para ajustar su código (el argumento que sigue a -e) en este bucle:

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

(-n es igual pero sin el bloque continuar).

El <>operador vacío es equivalente a readline *ARGV, y eso abre cada argumento sucesivamente como un archivo para leer. No hay forma de influir en el manejo de errores de esa apertura implícita, pero puede hacer que la advertencia que emite sea fatal (tenga en cuenta que esto también afectará a varias advertencias relacionadas con el modificador -i):

perl -Mwarnings=FATAL,inplace -pe 1 foo && echo ok
Grinnz
fuente
@MarkReed inplace es la categoría de advertencias en la que estamos interesados. No hay razón para afectar otras advertencias.
Grinnz
De advertencias :The presence of the word "FATAL" in the category list will escalate warnings in those categories into fatal errors in that lexical scope.
Grinnz
Correcto, inplacees la categoría; sin ella, -Mwarnings=FATALsignifica FATAL => all, lo que no queremos. Entendido.
Mark Reed
4

Establezca una bandera en el cuerpo del bucle, verifique la bandera en el bloque FINAL al final del revestimiento.

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

Tenga en cuenta que solo falla cuando no se procesó ningún archivo.

Para informar el problema cuando no se han encontrado todos los archivos, puede usar algo como

perl -pe 'BEGIN{ $files = @ARGV} $found++ if eof; ... ;END {die "Some files not found" unless $files == $found}'
choroba
fuente
1
Si se supone que su script toma archivos como argumentos en lugar de leerlos desde stdin, sería una alternativa más ligera a esta solución BEGIN{die "File not found" unless -f $ARGV[0]}. (Digo más ligero, porque no implica establecer una bandera y agregar 2 piezas de códigos)
Dada
También se supone que todos los archivos son de longitud distinta de cero.
Tanktalus