1

As for the cat command, which returns an exit code other than 0 if at least one file in the list does not exist, but continuing its execution, I would also like the same behavior for the "perl" command, which while continuing its execution, unfortunately it does not return a non-0 exit code when encountering one or more missing files.

This solution provided by another topic Why is my Perl in-place script exiting with a zero exit code even though it's failing?:

perl -p -i -e 'BEGIN{ -f $ARGV[0] or die"no file" } s/foo/bar/' non-existent-file.txt

Correctly returns a non-0 exit code when a file is not found but does not continue executing for other files. Indeed this:

perl -p -i -e 'BEGIN{ -f $ARGV[0] or die"no file" } s/foo/bar/' non-existent-file.txt existent-file.txt

doesn't give the output of the second file but only the error for the first non-existent file.

How can I solve the problem?

oguz ismail
  • 1
  • 16
  • 47
  • 69
Mario Palumbo
  • 693
  • 8
  • 32
  • There's no way to configure reading from `ARGV`. If you don't like how it works, you'd have to reimplement it with your modifications. (In other words, get rid of `-p`, and use `for ( @ARGV ) { ... }`.) – ikegami May 09 '23 at 13:29
  • I don't understand the problem with an answer (ikegami's) in the link you provide? It continues processing but it exits with non-zero if there were errors -- isn't that what you are asking for? In the example you took from that link, shown here, there is an explicit `die` ... of course it exits at that point? – zdim May 09 '23 at 16:54
  • LIke `perl -MList::MoreUtils=any -wpE'BEGIN { $fail = 7 if any { not -f } @ARGV } END { exit ($fail //= 0) }' nofile yesfile`. Then `echo $?` – zdim May 09 '23 at 16:59
  • In short, you can `exit` with a desired code in an `END` block, and that will be in shell's `$?`. So keep a flag throughout that gets set for error conditions and use it for `exit`. (Or better yet an array like in mob's answer so you can actually print those errors as well) – zdim May 09 '23 at 19:13

1 Answers1

2

Put your die statement in an END block instead of a BEGIN block.

perl -p -i -e 'BEGIN{ @nf=grep ! -f $_, @ARGV}
    END{die "not found: @nf" if @nf} 
    s/foo/bar/' file1 file2 ...
mob
  • 117,087
  • 18
  • 149
  • 283