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.