¿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?

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

@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}'

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.