perlsystem-callsdie

Perl: After a successful system call, "or die" command still ends script


I am using the following line to make a simple system call which works:

system ("mkdir -p Purged") or die "Failed to mkdir." ;

Executing the script does make the system call and I can find a directory called Purged, but the error message is still printed and the script dies. What is wrong with my syntax?


Solution

  • That would be a little confusing, wouldn't? - Leonardo Herrera on Ikegami's answer

    Yes, it is confusing that the system command inverts true and false in Perl, and creates fun logic like this:

    if ( system qw($command) ) {
        die qq(Aw... If failed);
    }
    else {
        say qq(Hooray! It worked!);
    }
    

    But, it's understandable why the system command does this. In Unix, an exit status of zero means the program worked, and a non-zero status could give you information why your system call failed. Maybe the program you were calling doesn't exist. Maybe the program sort of worked as expected. For example, grep returns an exit code of 1 when grep works, but there were no matching lines. You might want to distinguish when grep returns zero, one, or a return code greater than one. (Yes, I know it's silly to use a system call to grep in a Perl program, but that's the first example I could think of).

    To prevent casual confusion, I create a variable that holds the exit status of my system command instead of testing the output of system directly:

    my $error = system qw($command);
    if ($error) {
        die qq(Aw... It failed);
    }
    else {
        say qq(Hooray! It worked!);
    }
    

    It's completely unnecessary, and people who work with Perl should know that system reverses Perl's definition of true and false, but if I hadn't had my coffee in the morning, I may miss it as I go over someone else's code. Doing this little step just makes the program look a bit more logical.

    The Perldoc of system give you code that allows you to test the output of your system command to see exactly what happened. (If there was an error, or a system interrupt signal killed the system call). It's nice to know if you need to interrogate your system return value to figure out what went wrong.