I am using command-line perl to perform a inplace substitution in a file. This is the code: (note the root perm with sudo)
sudo perl -i -pe "s/foo/bar/" config.txt
If this succeeds, 'echo $?' return 0. Now I make the file un-writable even for root using chattr like this:
sudo chattr +i config.txt
I run the same perl command and it fails with this error:
Can't remove config.txt: Operation not permitted, skipping file.
Which is fine. However, 'echo $?' still returns 0 in this case. Why is this so? Shouldn't it return a non-zero value indicating an error?
The problem is that Perl does not come back with a non-zero exit status for this condition (sudo
passes on the exit status of the command it was given), which is a bit vexing. You can work around the problem by recognizing that the line-reading loop is never entered if the file fails to be renamed and handle it with a flag:
sudo perl -i -ne 's/foo/bar/; print; $wrk = 1; }{ $wrk or exit 1' config.txt
The Eskimo greeting (or butterfly) "operator" }{
introduces an END
block, in a way; what comes after it is executed when the loop reading lines from the file has ended. The way it works is described here.
The caveat is that this will also report an error if config.txt
is empty. A shorter if a bit hackier way is to use the special $.
line counter variable for the same purpose:
sudo perl -i -ne 's/foo/bar/; print; }{ $. or exit 1' config.txt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With