perldie

Perl: `die` did not work upon opening a nonexistent gz file using gzip


The following script creates a gziped file named "input.gz". Then the script attempts to open "input.gz" using gzip -dc. Intuitively, die should be triggered if a wrong input file name is provided. However, as in the following script, the program will not die even if a wrong input file name is provided ("inputx.gz"):

use warnings;
use strict;

system("echo PASS | gzip -c > input.gz");

open(IN,"-|","gzip -dc inputx.gz") || die "can't open input.gz!";

print STDOUT "die statment was not triggered!\n";

close IN;

The output of the script above was

die statment was not triggered!
gzip: inputx.gz: No such file or directory

My questions is: why wasn't die statement triggered even though gzip quit with error? And how can I make die statement triggered when a wrong file name is given?


Solution

  • It's buried in perlipc, but this seems relevant (emphasis added):

    Be careful to check the return values from both open() and close(). If you're writing to a pipe, you should also trap SIGPIPE. Otherwise, think of what happens when you start up a pipe to a command that doesn't exist: the open() will in all likelihood succeed (it only reflects the fork()'s success), but then your output will fail--spectacularly. Perl can't know whether the command worked, because your command is actually running in a separate process whose exec() might have failed. Therefore, while readers of bogus commands return just a quick EOF, writers to bogus commands will get hit with a signal, which they'd best be prepared to handle.

    Use IO::Uncompress::Gunzip to read gzipped files instead.