Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 271
user3481208 Avatar asked Mar 31 '14 13:03

user3481208


People also ask

What does die function do in Perl?

The die() function can be used to stop the script and can be used to display a message to the end user. It can be used at the right side of the OR ( || ) operator and at left side can be any expression like the eval() function.

How do I exit a shell in Perl?

According to cmd.exe /? /C carries out the command specified by string and then terminates. For that matter, you can just run perl yourscript.pl and leave cmd.exe out of it entirely.

What is System command in Perl?

Perl's system command provides a way to execute a shell command on the underlying platform. For example, if you are running on a Unix platform, the command: system("ls -l") will print a long listing of files to stdout.


2 Answers

system returns the exit status of the command it calls. In shell, zero exit status means success. You have to invert the logic:

0 == system qw(mkdir -p Purged) or die "Failed to create the dir\n";
like image 80
choroba Avatar answered Sep 16 '22 22:09

choroba


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.

like image 45
David W. Avatar answered Sep 18 '22 22:09

David W.