Quelle est la meilleure façon (idiomatique) d'échouer le script perl (exécuté avec -n / -p) lorsque le fichier d'entrée est introuvable?

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

J'aimerais vraiment que le script perl échoue lorsque le fichier n'existe pas. Quelle est la manière "correcte" de faire échouer -p ou -n lorsque le fichier d'entrée n'existe pas?

William Pursell
la source

Réponses:

6

Le commutateur -p n'est qu'un raccourci pour encapsuler votre code (l'argument suivant -e) dans cette boucle:

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

(-n est le même mais sans le bloc continue.)

L' <>opérateur vide est équivalent à readline *ARGV, et cela ouvre chaque argument successivement sous forme de fichier à lire. Il n'y a aucun moyen d'influencer la gestion des erreurs de cette ouverture implicite, mais vous pouvez rendre l' avertissement qu'il émet fatal (notez que cela affectera également plusieurs avertissements liés au commutateur -i):

perl -Mwarnings=FATAL,inplace -pe 1 foo && echo ok
Grinnz
la source
@MarkReed inplace est la catégorie des avertissements qui nous intéresse. Il n'y a aucune raison d'affecter les autres avertissements.
Grinnz
Des avertissements :The presence of the word "FATAL" in the category list will escalate warnings in those categories into fatal errors in that lexical scope.
Grinnz
À droite, inplaceest la catégorie; sans cela, cela -Mwarnings=FATALsignifie FATAL => allque nous ne voulons pas. je l'ai.
Mark Reed
4

Définissez un drapeau dans le corps de la boucle, vérifiez le drapeau dans le bloc FIN à la fin de la ligne.

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

Notez qu'il échoue uniquement quand aucun fichier n'a été traité.

Pour signaler le problème lorsque tous les fichiers n'ont pas été trouvés, vous pouvez utiliser quelque chose comme

perl -pe 'BEGIN{ $files = @ARGV} $found++ if eof; ... ;END {die "Some files not found" unless $files == $found}'
choroba
la source
1
Si votre script est censé prendre des fichiers comme arguments plutôt que de les lire depuis stdin, une alternative plus légère à cette solution serait BEGIN{die "File not found" unless -f $ARGV[0]}. (Je dis plus léger, car cela n'implique pas de mettre un drapeau et d'ajouter 2 morceaux de codes)
Dada
Suppose également que tous les fichiers sont de longueur non nulle.
Tanktalus