tags:

views:

156

answers:

2

I am using this script for a piped log setup in Apache 2:

#!/usr/local/bin/perl

$|=1; # Use unbuffered output
while (<STDIN>)
{
   if (<STDIN> =~ m/(.php|.html|.htm|.dhtml|.cpp|.h|.c|.txt|.pdf|.pl)$/)
      {system("beep");}
}

I am sending in the directive %f to give it the filename. As you can tell, it checks to see if the requested filename is a content file. If so, it tells the system to beep. For some reason however, the server only beeps every two times a content page is accessed. Does anyone know why this might happen?

I'm pretty sure it has to do with the way I'm using <STDIN>, because this is my first Perl script.

+4  A: 

You read the first line with the while(), then you read another in the if().

Change the 'if' to: if($_ =~ ...)

Andrew Barnett
Or just if (/(.php|.html|.htm|.dhtml|.cpp|.h|.c|.txt|.pdf|.pl)$/) perl assumes you mean to do the match on $_ if its not given.
Copas
+4  A: 

Try:

while ( <> ) {
  system("beep") if /php|pl.../;
}
chris
That looks a lot cleaner, but I don't see how the if statement is making a comparison. Wouldn't you need a ~= somewhere? Also, how come you replaced <STDIN> with just <>?
Cory Walker
/REGEXP/ is equivalent to $~ =~ /REGEXP/ by default. <> means all files specified in the command line, or <STDIN> if no files were specified.
pts
See perldoc perlvar. Look for ARGV.
Sinan Ünür
Thanks, I finally got it after some trouble with a missing closing quote.
Cory Walker
@Cory: In the for loop each line of <STDIN> is split into the default variable $_ if you don't give perl anything to match against with a regular expression it assume that you want to perform the match on the default variable $_. This is part of why perl is so elegant/hated by people who don't use it. Its simplicity adds complication.
Copas