Skip to content
Advertisement

need perl to die when implicit open fails

I’m trying to migrate a sed script to a perl one-liner, because perl supports non-greedy regexp. I’ve taken advices from Non greedy (reluctant) regex matching in sed? and Why is my Perl in-place script exiting with a zero exit code even though it’s failing?

I need my oneliner to exit with non-zero status if it failed to open the file.

Unfortunately, checking -f $ARGV[0] is unreliable, because the file may exist and still be inaccessible.

One idea is to add some perl code to execute between all files in command line, but I can’t find one. END is executed once and if the last file succeeded, then it won’t know that previous files failed.

touch aaa.txt
chmod 000 aaa.txt
perl -i -pe 'BEGIN { -f $ARGV[0] or die "fatal: " . $!; }' aaa.txt; echo $?

_

Can't open aaa.txt: Permission denied.
0

Advertisement

Answer

The Can't open ... text is a warning. You can trap that using the $SIG{__WARN__} signal handler.

As the only warnings you should be getting are from the implicit <> operator in the loop supplied by the -p switch you can rewrite your code like this

perl -i -pe 'BEGIN { $exit = 0; $SIG{__WARN__} = sub { $exit = 1; warn @_} } END { $? = $exit}' aaa.txt; echo $?

This sets $exit to 0 at the start of the script and sets it to 1 if there is a warning. The END block assigns the value of $exit to $? which will be the exit code of the script once it ends.

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement