perl - 如果列出的文件中至少有一个不存在,则获取非零退出代码

perl - 如果列出的文件中至少有一个不存在,则获取非零退出代码

至于 cat 命令,如果列表中至少有一个文件不存在,它会返回 0 以外的退出代码,但继续执行,我也希望“perl”命令有同样的行为,它在继续执行时,不幸的是,当遇到一个或多个丢失的文件时,它不会返回非 0 的退出代码。

该解决方案由另一个主题提供https://stackoverflow.com/questions/22192300

perl -p -i -e 'BEGIN{ -f $ARGV[0] or die"no file" } s/foo/bar/' non-existent-file.txt

当找不到文件时正确返回非 0 退出代码,但不会继续执行其他文件。事实上是这样的:

perl -p -i -e 'BEGIN{ -f $ARGV[0] or die"no file" } s/foo/bar/' non-existent-file.txt existent-file.txt

没有提供第二个文件的输出,而只提供第一个不存在的文件的错误。

我该如何解决这个问题?

答案1

我也不是一个 Perl 专家,但是你只评估第一个参数,并在文件不存在后立即终止你的脚本...如果第一个参数是一个不存在的文件,这既不会评估作为参数传递的所有文件,也不会继续处理其他文件。

因此,当您传递多个参数时,您的脚本将不会按预期工作(文件名)即可。

您需要首先使用例如评估所有命令行参数,foreach my $arg (@ARGV) { ... }然后相应地设置退出代码,并在最后使用该代码退出。

即这样的:

perl -p -e 'my $exit_code; BEGIN{
foreach my $arg (@ARGV) {-f $arg or $exit_code = 2} }
END{exit($exit_code)}
s/foo/bar/' non-existent-file.txt existent-file.txt

注意可能会节省你的时间): 据我所知,它die没有自己的退出状态,也不会“直接”改变脚本的退出状态……因此,2您看到的退出代码号实际上是-f $ARGV[0]……no such file or directory这些代码号是种类有限且各具特色...因此,在受控环境中手动分配/设置它们是完全没问题的,尽管传递的参数可能是目录,那么它可能会导致不同的错误编号,但这就是“受控”的意义所在,因为您可以更改-f-e例如或使用条件进行双重评估,甚至添加您自己的扩展错误评估/包含代码来做你想做的事情。

此外,die可以有一个副作用(例外)这将导致额外的错误代码,例如22无效的论点)从而污染你的脚本,如果你想保留一些实际的退出状态,这可能不是你想要的......看看为什么这里...然而你也许能够部分地控制/中和这种副作用(虽然可能不可靠...请exit改用) 类似于eval{die "blabla" ... }和,在这种情况下这也可能会直接改变脚本的退出状态。

不过,你也许可以同时使用die不是 exit-f $ARGV...并同时保留实际的退出状态,同时不会过早地终止脚本,如果您正确地将评估移动到一个END块中,如下所示:

perl -p -e 'my @arr; BEGIN{@arr = @ARGV}
END{ foreach my $arg (@arr) { -f $arg or die"no file"} }
s/foo/bar/' non-existent-file.txt existent-file.txt

答案2

perl -p -i -e 'BEGIN { -f $ARGV[0] or push @nofile, $ARGV[0]; } END { die "no file: ". join ", ", @nofile if @nofile; } s/foo/bar/' non-existent-file.txt existent-file.txt

相关内容