The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Странное поведение цикла при считываии хэша"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (Perl)
Изначальное сообщение [ Отслеживать ]

"Странное поведение цикла при считываии хэша"  +/
Сообщение от lv2 email(ok) on 08-Май-12, 09:15 
Здравствуйте,

Пытаюсь реализовать своими рукуми первый раз в жизни перл скрипт по заданию начальника.
Занятие при  отсутствии знаний оказалось непростым.
Изначально задание следующее:
Необходимо отследить в логах апача определенные IP аддреса. Есть список этих адресов.
Я вчера написал bash скрипт, но он за ночь прошел очень мало, поэтому начальник сказал писать на перле используя Хэш.

В хэш я решил занести эти IP адреса из файла в поля ключей. И присвоить им значения 0.
По мере парсинга и нахождения значение должно прибавляться к тому ключю который нашло в логе.
Для эксперимента взял 7 адресов, создал файл адресов с ними и создал второй файл(анализируемый). В него продублировал те же самые адреса 2 раза

Написал кой какой скрипт (после 5ти часов в инете), расставил по нему принтов чтоб понимать как он работает и работает ли вобще. И результат анализа стал выводить в аутпут файл.

На определенной  стадии заметил странное поведение. В Выводу принтов в консоль было 8 входов во внешний цикл (где подставляется искомый адрес) и 15 входов во второй цикл (где перебираются строки анализируемого файла). По логике должно быть 7 и 14. Иду в файлы, замечаю снизу пустую строку. Убираю в файле имитирующем логфайл апача - все ок. Убираю в файле IP адресов - вхождений во внутренний цикл становится только 2 вместо 14 или дажк 15 как было. Возвращаю пустую строку  - снова 15.

Не могли бы вы посянить что именно происходит и почему скрипт так себя ведет?


Вот в таком порядке идут IP адреса  в файле /tmp/1ip
1.197.174.131
1.197.174.247
24.187.239.58
27.189.35.33
41.34.142.120
41.35.176.113
41.35.180.236


А вот в таком они почему то заносятся в хэш
1.197.174.247    0
41.35.176.113    0
41.34.142.120    0
1.197.174.131    0
24.187.239.58    0
41.35.180.236    0
27.189.35.33    0


вот сам скрипт

#!/usr/bin/perl -w

use warnings;
$to="/tmp/result";
$weblog="/tmp/2log";
####Populate hash
my %hash = do {
    open my $f, '</tmp/1ip' or die $!;
    map {chomp; $_ => 0} <$f>;
};


#Opens logfile
open(FH,"$weblog")or die"Can not open $weblog: $!\n";

#Defines output file
open(NEW,">>$to");


while (($key, $value) = each(%hash)){

$a=$key;
$b=$value;

while(<FH>){

     next if (!/$a/);

print " $_ internal cycle \n";
if(/$a/){print NEW "$_";$b++}
next;
}
print "$a external\n";
print NEW "\n $a: $b: $weblog\n";
next;
}

Вот вывод в консоль до убирания пустой строки

1.197.174.131
internal cycle
1.197.174.247
internal cycle
24.187.239.58
internal cycle
27.189.35.33
internal cycle
41.34.142.120
internal cycle
41.35.176.113
internal cycle
41.35.180.236
internal cycle
1.197.174.131
internal cycle
1.197.174.247
internal cycle
24.187.239.58
internal cycle
27.189.35.33
internal cycle
41.34.142.120
internal cycle
41.35.176.113
internal cycle
41.35.180.236
internal cycle

internal cycle
external
41.35.176.113 external
41.34.142.120 external
24.187.239.58 external
41.35.180.236 external
27.189.35.33 external
1.197.174.247 external
1.197.174.131 external


И после

1.197.174.247
internal cycle
1.197.174.247
internal cycle
1.197.174.247 external
41.35.176.113 external
41.34.142.120 external
1.197.174.131 external
24.187.239.58 external
41.35.180.236 external
27.189.35.33 external

Заранее спасибо за помощь.

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Странное поведение цикла при считываии хэша"  +/
Сообщение от ACCA (ok) on 09-Май-12, 07:27 
> Не могли бы вы посянить что именно происходит и почему скрипт так
> себя ведет?

Потому, что ты поискал первый ключ до конца файла, а потом искать стало негде.

Кроме того, неясно откуда у тебя файл. Если хоть каким-то боком приложена винда - ожидай в конце строки CRLF, с которыми chomp не справляется.

> А вот в таком они почему то заносятся в хэш
> 1.197.174.247 0

У хэша нет порядка, он изображает неупорядоченное множество. Более того, в Perl приняты специальные меры, чтобы порядок ключей оказывался случайным при каждом запуске. Поэтому сервера на PHP, Java и всяких .NET можно легко свалить длинным запросом, а Perl - нет.


> вот сам скрипт

В первый раз вижу JavaScript программу, писаную Perl'ом. :)

> #!/usr/bin/perl -w
> use warnings;

Это тавтология. Следовало бы


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

Забудешь кого-нибудь из этой пары - есть шанс прокатиться в дурку.


> my %hash = do {
>     open my $f, '</tmp/1ip' or die $!;
>     map {chomp; $_ => 0} <$f>;
> };

1. значение 0 - плохая идея, хуже него только undef. Сделай 1
2. если адресов немного - зачем файл? Сделай статический список


> while (($key, $value) = each(%hash)){

Не пользуйся each - это реликт Perl 4, с побочными эффектами.

Не открывай файлы без крайней нужды, пользуйся <>, где возможно.



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

use io IN => ':crlf';    # для DOS
binmode STDIN, ':crlf';

my %hash = (
   '1.197.174.131'  => 1,
   '1.197.174.132'  => 1,
   '1.197.174.133'  => 1,
   '1.197.174.134'  => 1,
.....
);
my %count;

while (<>) {
   while (/\b(\d+\.\d+\.\d+\.\d+)\b/go) {
       $count{$1}++ if $hash{$1}; # домашнее задание - победи autovivification
   }
}

foreach my $k (sort keys %count) {
   print "$k: $count{$k}\n";
}


Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру