system return value makes for strange logic

W

wana

I was writing a short script to create a mysql database and kept getting
confusing results:

system("mysqladmin --user='$user' --password='$pass' create $db")
or die "$db not created due to error\n";

The function lead to die being called and printing the error message but the
database was being created successfully. I changed it to:

system("mysqladmin --user='$user' --password='$pass' create $db")
and die "$db not created due to error\n";

and even though it doesn't look right at first glance, it makes sense
because system apparently returns 0 with success and numbers > 0 for
failure. I read about it in 'Programming Perl' and saw the explanation
that the return value gives information about the nature of the failure.
Isn't this strange? Don't we normally look to $! for errors and consider 0
to mean failure? I can accept it, but 'do and die' sounds funny compared
to the usual 'do or die'.

wana
 
C

Chris Cole

I was writing a short script to create a mysql database and kept getting
confusing results:

system("mysqladmin --user='$user' --password='$pass' create $db")
or die "$db not created due to error\n";

The function lead to die being called and printing the error message but the
database was being created successfully. I changed it to:

system("mysqladmin --user='$user' --password='$pass' create $db")
and die "$db not created due to error\n";

and even though it doesn't look right at first glance, it makes sense
because system apparently returns 0 with success and numbers > 0 for
failure. I read about it in 'Programming Perl' and saw the explanation
that the return value gives information about the nature of the failure.
Isn't this strange? Don't we normally look to $! for errors and consider 0
to mean failure? I can accept it, but 'do and die' sounds funny compared
to the usual 'do or die'.
Try this for a more sensible format:

system("mysqladmin --user='$user' --password='$pass' create $db") == 0 or
die "$db not created due to error\n";

BTW why aren't you using perl DBI? That will give you more control over
errors and the like.
Chris.
 
W

wana

Try this for a more sensible format:

system("mysqladmin --user='$user' --password='$pass' create $db") == 0 or
die "$db not created due to error\n";

BTW why aren't you using perl DBI? That will give you more control over
errors and the like.
Chris.

I didn't realize you could create a database with DBI. I'll have to read up
on it more. I actually use DBI with CGI and MySQL a lot but I thought you
had to create the database first and specify it for DBI->connect. Thanks
for the suggestions. I like your == 0 or alternative.

wana
 
E

Eric Bohlman

and even though it doesn't look right at first glance, it makes sense
because system apparently returns 0 with success and numbers > 0 for
failure. I read about it in 'Programming Perl' and saw the
explanation that the return value gives information about the nature
of the failure. Isn't this strange? Don't we normally look to $! for
errors and consider 0 to mean failure? I can accept it, but 'do and
die' sounds funny compared to the usual 'do or die'.

The reason is that system() returns the exit status of the program it runs.
What that status is is under the program's control, not perl's. The
convention (which again has nothing to do with Perl) is that a program
exits with 0 on success and any number of non-zero values upon failure.
Why? Because there's only one way a program can succeed, but quite a few
ways it can fail (the number of such ways varying from program to program)
and it's helpful if it can signal *why* it failed.
 
A

Arndt Jonasson

Eric Bohlman said:
The reason is that system() returns the exit status of the program it runs.
What that status is is under the program's control, not perl's. The
convention (which again has nothing to do with Perl) is that a program
exits with 0 on success and any number of non-zero values upon failure.
Why? Because there's only one way a program can succeed, but quite a few
ways it can fail (the number of such ways varying from program to program)
and it's helpful if it can signal *why* it failed.

The history of that convention has mainly to do with Unix. I think VMS
is one system that treats return status from processes differently. At
least the C standard committee found it necessary to invent
preprocessor symbols for denoting successful and failing process exit,
since 0 for success was not universal.

Since I'm on the subject: it often happens in Perl code that people
take the return value from 'system', divide it by 256, and think they
have the exit status. They have that, if the process didn't dump core
(if we're on a Unix system). If it dumped core, the lowest bits are
nonzero. Thus, a program crash may be misinterpreted as successful
exit. The doc for 'system' does say this, but it may be easy to forget.
 
D

David Gale

Quoth Arndt Jonasson said:
Since I'm on the subject: it often happens in Perl code that people
take the return value from 'system', divide it by 256, and think they
have the exit status. They have that, if the process didn't dump core
(if we're on a Unix system). If it dumped core, the lowest bits are
nonzero. Thus, a program crash may be misinterpreted as successful
exit. The doc for 'system' does say this, but it may be easy to
forget.

Actually, they lose more than just whether or not it dumped core. If it was
interrupted by *any* signal, that goes in the lower bits.

Try:
perl -e 'print system("sleep 30")."\n";'
and hit Ctl-C while it's sleeping.
 
J

Jürgen Exner

wana said:
system("mysqladmin --user='$user' --password='$pass' create $db")
or die "$db not created due to error\n";

The function lead to die being called and printing the error message
but the database was being created successfully. I changed it to:

system("mysqladmin --user='$user' --password='$pass' create $db")
and die "$db not created due to error\n";

and even though it doesn't look right at first glance, it makes sense
because system apparently returns 0 with success and numbers > 0 for
failure.

Why don't you just check the documentation for the functions you are using?
It's explained right there in the third paragraph of "perldoc -f system".

jue
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,008
Latest member
Rahul737

Latest Threads

Top