Exploding check commands batman ...

Paul L. Allen pla at softflare.com
Fri Jul 1 21:01:44 CEST 2005


Andreas Ericsson writes: 

> Paul L. Allen wrote:

>>  Easy for options which take string arguments and
>> where the string "0" is never valid or sensible:
>  
> The string "0" and str[0] = 0 are two quite different things.

In C they are.  In perl there are some overlaps between "0", the
null string, the number 0 and unitialized variables, depending on what
exactly you do with them. 

   Variable is      Is defined?    Boolean val    Num val    String val
   -----------      -----------    --------       -------    ----------
   uninitialized    NO             false          0          null string
   null string      yes            false          0          null string
   number 0         yes            false          0          "0"
   string "0"       yes            false          0          "0"
   string "0.0"     yes            TRUE           0          "0.0"
   string "00"      yes            TRUE           0          "00" 

In strict mode uninitialized variables cannot be used in comparisons.
So if somebody does manage to do something that results in a variable
holding an option being uninitialized, as opposed to being initialized
with the null string, things break.  Outside of strict mode an
uninitialized variable is false in a boolean context, 0 in a numeric
context and the null string in a string context; in strict mode all you
can do with an unitialized variable without causing an error is assign
to it. 

That may seem arbitrary and bizarre to you, but generally that
behaviour is exactly what you want most of the time in a language where
strings that look like numbers can be used as numbers and numbers can
be used as strings. 

    $x = "5";
    $x++;
    print "$x\n";
    print "The value is $x\n";
    $x = "The value is $x";
    print "$x\n"; 

gives the number 6 as the first output (and $x is now stored as a number 
rather than a string), 'The value is 6' as the second output (and $x is
still stored as as number), the third output is the same but now $x is
now stored as a string again. 

On the other hand, 

   $x = 'five';
   $x++;
   print "$x\n"; 

gives an answer of one (the string 'five', when evaluated as a number,
is equivalent to 0). 

But 

   $x = '5 four three two 1';
   $x++;
   print "$x\n"; 

Gives 6 as the answer.  Perl takes as much as it can from the start of
the string that looks like a number and uses it that way.  So 0 and "0"
are both false if used as a boolean, because you expect 0 to be false;
0 and "0" are both zero when used as numerics, because you expect 0
to be zero; and both "0" when used as strings, because you expect that
as well.  Admittedly, it would get very confusing if it were not for
perl having different operators for manipulating numbers and string: 

 $x = '0';
 $y = 0;
 $z = '7';
 print "$x$y$z\n";
 print $x + $y + $z, "\n"; 

gives '007' for the first answer and 7 for the second. 

It does make sense.  Sort of.  Once you get used to it.  Where perl gets
truly bizarre is that you can do 

   $x = 'perl';
   $x++;
   print "$x\n"; 

and the output is 'perm', provided you didn't use $x as a string between
defining it and the increment, and it only works with auto-increments.
There's a reason for all that too, and it's not so you can make hair
jokes about perl. 

> POSIX quite clearly states that empty arguments are still arguments. Any 
> implementation doing otherwise is decidedly broken, even if it errs on the 
> side of prudence.

There's a difference between the null string and being uninitialized. 

   check_foo -x '' 

Means $opt_x contains the null string. 

   check_foo -x 

IF you can somehow sneak it past the shell and the GetOpt module (or
whatever method the plugin uses) could conceivably result in $opt_x being
undefined, unless something takes steps to ensure otherwise.  And that
would result in comparisons causing output to standard error and returning
what will almost certainly be an incorrect status code for the situation. 

This situation happens in perl plugins that parse output using regular
expressions when they encounter output the author didn't expect.  One or
more variables are left undefined because the output doesn't match a
regex, the variable is used in a comparison and bang (the 1.3.1
check_ntp comes to mind). 

-- 
Paul Allen
Softflare Support 



-------------------------------------------------------
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477&alloc_id=16492&op=click
_______________________________________________
Nagios-users mailing list
Nagios-users at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nagios-users
::: Please include Nagios version, plugin version (-v) and OS when reporting any issue. 
::: Messages without supporting info will risk being sent to /dev/null





More information about the Users mailing list