5

I have a one-liner Perl search and replace that looks roughly like this:

perl -p -i -e 's/foo/bar/' non-existent-file.txt

Because the file doesn't exist (which isn't intentional, but this is part of an automated build script, so I want to protect against that), Perl exits with this error:

Can't open non-existent-file.txt: No such file or directory.

However, the exit code is still zero:

echo $?
0

Am I doing something wrong? Should I be modifying my script, or the way I'm invoking Perl? I was naively assuming that because Perl couldn't find the file, it would exit with a non-zero code.

Andrew Ferrier
  • 16,664
  • 13
  • 47
  • 76
  • 5
    Perl does not automatically exit when it is unable to open a file. That one liner is a real script for Perl, so when it comes to the open, it just tries to open the file. It is not able to and thus writes to STDERR but it can not know whether there is something else to do in the rest of the script and so it just goes on. In this case, there is nothing else to do as it would just loop over the lines of the file. And thus it finishes normally at the end of the script, returning zero. If you want your script to `die` or `exit` with some specific error code, you have to add that to the script. – DeVadder Mar 05 '14 at 09:02

2 Answers2

5

Because that's not a fatal error. If you use perl -pe'...' file1 file2, it would continue to process file2 even if file1 doesn't exist.

The following causes the issuance of any warning to result in a non-zero exit code.

$ perl -i -pe'
   BEGIN {
      $SIG{__WARN__} = sub {
         ++$error;
         print STDERR $_[0];
      };
    }

    END { $? ||= 1 if $error; }

    s/foo/bar/g;
' file1 file2

This means that file2 will still be processed even if file1 doesn't exist, but the exit code will be non-zero.

ikegami
  • 367,544
  • 15
  • 269
  • 518
4

You can force error by dying,

perl -p -i -e 'BEGIN{ -f $ARGV[0] or die"no file" } s/foo/bar/' non-existent-file.txt
mpapec
  • 50,217
  • 8
  • 67
  • 127
  • Note: Doesn't handle permission errors or multiple files. Also, it dies when provided a pipe or socket. – ikegami May 09 '23 at 17:21