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.