LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Weird Perl Error (https://www.linuxquestions.org/questions/programming-9/weird-perl-error-78773/)

HappyDude 08-04-2003 01:19 AM

Weird Perl Error
 
Ok I'm having a really weird error in my script (its cut down from 77 lines):
Code:

# Open the file.

open(IP, '>>ip.txt');

# This part is devoted to logging the IP

if($IP =~ "10.10.*", "192.168.*")
{
print IP "Private ($IP) $realhour:$zerom$Minute $PMAM on $day[$WeekDay] $monthn[$months] $DayOfMonth, $zeroy$realyear\n";
print "IP: Logged";
} if($IP !~ "", "10.10*", "192.168*") {
print IP "$IP $realhour:$zerom$Minute $PMAM on $day[$WeekDay] $monthn[$months] $DayOfMonth, $zeroy$realyear\n";
print "IP: Logged";
} else {
print IP "Unknown IP at $realhour:$zerom$Minute $PMAM on $day[$WeekDay] $monthn[$months] $DayOfMonth, $zeroy$realyear\n";
print "IP: Unknown Error";
}
# Close the file.

In the error log it says:
Code:

[Sun Aug 03 23:13:06 2003] [error] [client 10.10.10.100] Useless use of not in void context at /var/www/cgi-bin/print.pl line 74.
[Sun Aug 03 23:13:06 2003] [error] [client 10.10.10.100] Useless use of a constant in void context at /var/www/cgi-bin/print.pl line 74.
[Sun Aug 03 23:13:06 2003] [error] [client 10.10.10.100] Name "main::IsDST" used only once: possible typo at /var/www/cgi-bin/print.pl line 6.
[Sun Aug 03 23:13:06 2003] [error] [client 10.10.10.100] Name "main::Second" used only once: possible typo at /var/www/cgi-bin/print.pl line 6.
[Sun Aug 03 23:13:06 2003] [error] [client 10.10.10.100] Name "main::DayOfYear" used only once: possible typo at /var/www/cgi-bin/print.pl line 6.

Its weird though because it doesn't affect my script at all. The only reason I care is because I want a clean log file. Any help?

TheLinuxDuck 08-04-2003 08:50 AM

The problem here is that the if statements are an incorrect use of the =~ and !~ operators. These operators are used with pattern matching (such as m//, s///), not with standard strings.

Consider the following code:
Code:

#!/usr/bin/perl
use strict;
use warnings;

# define some IP's to parse
my($IPList) = [qw(10.10.2.4 192.168.1.4 10.5.4.23 192.168.1.6 4.3.2.1)];

# loop through IP's, and test for certain IP's
for my $IP(@$IPList) {
  if($IP =~ "10.10*", "192.168*") {
    print $IP, " matches!\n";
  }
  if($IP !~ "", "10.10*", "192.168*") {
    print $IP, " doesn't match...\n";
  }
}

exit;

And the output:
Code:

~/perl/happydude> ./tests.pl
Useless use of not in void context at ./tests.pl line 14.
Useless use of a constant in void context at ./tests.pl line 14.
10.10.2.4 matches!
10.10.2.4 doesn't match...
192.168.1.4 matches!
192.168.1.4 doesn't match...
10.5.4.23 matches!
10.5.4.23 doesn't match...
192.168.1.6 matches!
192.168.1.6 doesn't match...
4.3.2.1 matches!
4.3.2.1 doesn't match...

You see the problem here? What you prolly want is something to test with a regexp, since perl doesn't have a way to know what the * means in a string, anyway (to my knowledge). Also, perl doesn't know what the code is trying to do by using the comma operator between tests. The code needs to specify what it's to test against each time. So, the code will need to convert the strings to patterns:
Code:

#  if($IP =~ "10.10*", "192.168*") {
  if($IP =~ /^10\.10/) {

Then, the way I'd combine the two is:
Code:

  if($IP =~ /^(10\.10|192\.168)/) {
That way, you get both in one shot. Then, instead of testing the IP again in the second test, you know at this point that it doesn't start with the two given ranges, so the code only needs to make sure it's not empty:
Code:

  if($IP =~ /^(10\.10|192\.168)/) {
    # blah blah do whatever here
  }
  elsif($IP ne "") {
    # we know that the IP doesn't start with 10.10 or 192.168,
    # and we know it's not empty, so do something else here
  }

Here is my revised version:
Code:

#!/usr/bin/perl
use strict;
use warnings;

my($IPList) = [qw(10.10.2.4 192.168.1.4 10.5.4.23 192.168.1.6 4.3.2.1)];

for my $IP(@$IPList) {
  if($IP =~ /^(10\.10|192\.168)/) {
    print $IP, " matches!\n";
  }
  elsif($IP ne "") {
    print $IP, " doesn't match...\n";
  }
}

exit;

and it's output:
Code:

~/perl/happydude> ./tests-fixed.pl
10.10.2.4 matches!
192.168.1.4 matches!
10.5.4.23 doesn't match...
192.168.1.6 matches!
4.3.2.1 doesn't match...

And that will fix your log errors!

HappyDude 08-04-2003 12:31 PM

EDIT: Found the problem.... I had used $ instead of @ for an array... Stupid me. Thankyou.

Thanks to your script and printing the variables in comments my log files are almost clean. The log file now says:
Code:

[Mon Aug 04 10:26:58 2003] [error] [client 10.10.10.100] Use of uninitialized value in conca
tenation (.) or string at /var/www/cgi-bin/print.pl line 72.

where line 72 is:
Code:

print "IP: Logged <!-- This is to make Apache happy: $lame -->";
Now I'm really confused.....

TheLinuxDuck 08-04-2003 12:57 PM

That error means the variable $lame is undefined. If lame is supposed to contain something, then find out where it's actually given a value, and verify that the value it's given isn't an undef. If all you need is a quick-fix, then right before line 72, put something that assigns $lame a value if it's not defined. Something like:

Code:

defined($lame) or $lame = "";
print "IP: Logged <!-- This is to make Apache happy: $lame -->";

That is nothing more than a hack, though, and won't fix the error, but it will stop generating the error in the logfile.


All times are GMT -5. The time now is 08:33 PM.