Forgotten Posted August 31, 2007 Posted August 31, 2007 Hey guys, This script isn't really meant to be run from a site but rather from the command line/shell/terminal. I really don't know much about perl at all and I wrote this script by researching and looking at other perl scripts. This script is meant to perform housecleaning on a log: it opens the log, removes every line containing an ip, and the tells you how many lines were removed. The trouble is that the script breaks and I have no clue what to do. #!/usr/bin/perl -w use strict; my $path = "/var/log/httpd/access_log"; my $ip = "127.0.0.1"; # Call subroutine remove($path,$ip); # Define remove subroutine sub remove { # Fix input variables my($log,$uip) = @_; # Check for valid path if (-e $log) { # Open log and turn contents into variable open(DATA, "<$log") or die "[-] Error: Logfile could not be opened: $!n"; my @data = <DATA>; close(DATA); # Declare status variables my $found = 0; my $count = 0; # Check if data exists if(@data) { # Run script for every line in $path foreach my $line (@data) { # For every line that contains the IP if($line =~m/$uip/) { open(LOG, ">$log") or die "[-] Error: Logfile could not be opened: $!n"; chomp($line) or die "[-] Error: Logfile could not be written to: $!n"; close(LOG); # Set find status to found $found = 1; # Increase number of IPs $count++; } } # No lines containing IP regex found if (!$found) { print "[-] $uip was not found in the logfile. Rest easy!n"; } else { print "[-] Log edit success! Removed $count instances of $uipn"; } } else { print "[-] Error: Data error?n"; } } else { print "[-] Error: $log does not exist or you have incorrect permissionsn"; } } Quote
cooper Posted August 31, 2007 Posted August 31, 2007 open(LOG, ">$log") or die "[-] Error: Logfile could not be opened: $!n"; chomp($line) or die "[-] Error: Logfile could not be written to: $!n"; close(LOG); Since when does the chomp function write to a file? It should just be removing some characters from $line. See here. You claim that 'the script breaks'. Could you be a tad more specific? Quote
Forgotten Posted August 31, 2007 Author Posted August 31, 2007 Sorry, I was a little tired. At this point in time, the script cannot open the log, make the data a variable. So when the if(@data) statement is made, it won't continue the script. Again, being tired I forgot the write the line that will replace the line with nothing, then chomp()... I believe that will work? Quote
cooper Posted August 31, 2007 Posted August 31, 2007 Do you really need that if statement? I mean, sure, from the looks of it it should pass it when the file is being read, but if it fails you simply get an empty array, which means no loops through the foreach statement. Are you sure the $log file exists and contains data? I don't believe you need to chomp. You want to loop through the array, deleting elements as you go, and end up with writing the whole array back to the file again. So in the foreach you'd use the splice call to cut away the lines, and only after the foreach loop you write the new lines to the file. Unless I'm mistaken your current code dump above opens the file for writing (as opposed to appending using the open(LOG,">>$log") call) on each non-matching element. So in other words your resulting file should never contain more than 1 line. It might explain why the if (@data) fails. Due to the truncating of the file (note, I'm no perl wiz. I don't know if this actually happens here) there is no data to be read. Am I making any sense here? Quote
SomeoneE1se Posted September 1, 2007 Posted September 1, 2007 I don't know perl but would it not be easer to put the whole file into memory(or rename it and delete it later) and write line by line back to the file as long as it doesn't have the localhost in that line... and I'm going to make an ass of you and me by(thinking this is for apache) and say you might want to use use a regex to make sure the IP is at the start so someone can't pass it as a referrer Quote
Lex Posted September 1, 2007 Posted September 1, 2007 How about you use this little perl one-liner : perl -pi.bak -e "s/127.0.0.1//g" log_file This should be run from command line . What it does is exactly what you need : it opens log_file ,searches for every occurence of 127.0.0.1 and removes it. The script makes a backup of the log_file , naming it log_file.bak ( just in case ). Hope this helps Quote
cooper Posted September 2, 2007 Posted September 2, 2007 mv logfile logfile.backup && grep -v $IP logfile.backup > logfile Quote
puredistortion Posted September 13, 2007 Posted September 13, 2007 Have you had a look at logrotate? This is a great log management utility that is included in most Linux distros. It is highly flexible and configurable. Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.