Incorrect command-line perl error value in $?

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?

Answers


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

Need Your Help

Add/Removing Options with JQuery

javascript jquery html

I'd like to add and remove options from one drop down menu using JQuery given a selected option in another.

Grouping items by attribute with AngularFire

angularjs firebase angularfire

I'm writing a small inventory app using Angular with Firebase as a backend for managing the inventory of a deep freezer (stuff could get lost in there forever!), and I'm having difficulty finding a...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.