当找不到输入文件时,如何最好地(习惯地)使 perl 脚本失败(使用 -n/-p 运行)?

How best (idiomatically) to fail perl script (run with -n/-p) when input file not found?

提问人:William Pursell 提问时间:12/7/2019 最后编辑:TanktalusWilliam Pursell 更新时间:12/7/2019 访问量:205

问:

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

我真的希望 perl 脚本在文件不存在时失败。当输入文件不存在时,使 -p 或 -n 失败的“正确”方法是什么?

pdrM的

评论


答:

6赞 Grinnz 12/7/2019 #1

-p 开关只是将代码包装在此循环中的快捷方式(-e 后面的参数):

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

(-n 相同,但没有 continue 块。

空运算符等效于 ,它将每个参数连续打开为要从中读取的文件。没有办法影响隐式打开的错误处理,但你可以使它发出的警告致命(注意,这也会影响与 -i 开关相关的几个警告):<>readline *ARGV

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

评论

0赞 Grinnz 12/7/2019
@MarkReed到位的是我们感兴趣的警告类别。没有理由影响其他警告。
0赞 Grinnz 12/7/2019
警告The presence of the word "FATAL" in the category list will escalate warnings in those categories into fatal errors in that lexical scope.
0赞 Mark Reed 12/7/2019
对,是类别;没有它,意味着,这是我们不想要的。明白了。inplace-Mwarnings=FATALFATAL => all
4赞 choroba 12/7/2019 #2

在循环的主体中设置一个标志,在 oneliner 末尾的 END 块中检查该标志。

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

请注意,仅当未处理任何文件时,它才会失败。

若要在未找到所有文件时报告问题,可以使用类似

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

评论

1赞 Dada 12/7/2019
如果您的脚本应该将文件作为参数而不是从 stdin 中读取,则此解决方案的较轻替代方法是 。(我说更轻,因为它不涉及设置标志和添加 2 段代码)BEGIN{die "File not found" unless -f $ARGV[0]}
0赞 Tanktalus 12/7/2019
还假定所有文件的长度都不为零。