Автор Тема: Помощ за perl  (Прочетена 4419 пъти)

axelic

  • Участници
  • ***
  • Публикации: 9
    • Профил
Помощ за perl
« -: Aug 05, 2006, 14:18 »
Здравейте, нужна ми е малко помощ за един скрипт. Налага ми се да направя известна промяна, но тъй като никога не съм работил с Perl ми идва доста нанагорно. Не познавам толкова добре синтаксиса, а и ...алгоритъма нещо ми убягва.
'<img'>

#!/usr/bin/perl

$critical = 27;
$lock = "temp.lock";

$string = `tail -1 tempdaemon.temp`;

($date,$time,$temp) = split(" ",$string);
if ($temp >= "$critical" && !(-f $lock)) {
print "Allert";
system("/usr/bin/touch $lock");
}

if ($temp < "$critical" && -f $_lock) {
`/bin/rm $lock`;


Както се вижда, скрипта дърпа переодично данни от един файл - tempdaemon.temp
в който се записва температурата всяка минута.
Скрипта е за уведомяване ако температурата се покачи над 27 градуса. Проблема е, че ако се качи над въпросните 27 градуса на всяка 1 минута изпраща съобщение, което е прекалено в случей, че температурата се задържи примерно на 27.1 в продължение на часове.
Идеята е така да се модифицира скрипта, че да праща съобщение само ако е над 27 градуса И разликата с предходното изпращане е повече от 0.5 градуса.
Благодаря много предварително. Всякакви идеи са добре дошли.

П.П. Хрумна ми, че евентуално може да има един файл в който да се записва стойността на една вариабла, която започва от "critical" и се променя само ако разликата между нея и "temp" е поне 0.5(в двете посоки), и съответно да има съобщение само при промяна на вариаблата. Така, че в момента въпроса е по скоро кода с който мога да трия/записвам във файл!



Активен

Lord Bad

  • Напреднали
  • *****
  • Публикации: 1667
  • Distribution: Fedora 13
  • Window Manager: GNOME
  • Jedi Knight
    • Профил
Помощ за perl
« Отговор #1 -: Aug 05, 2006, 17:16 »
Това, което ти трябва ще намериш тук. Успех.
Активен

Fuelled by Fedora 13 "Goddard"
====================================
Rock it!

axelic

  • Участници
  • ***
  • Публикации: 9
    • Профил
Помощ за perl
« Отговор #2 -: Aug 07, 2006, 19:46 »
Цитат (Lord_Bad @ Авг. 05 2006,18:16)
Това, което ти трябва ще намериш тук. Успех.

Много благодаря, но аз се надявах по скоро на директен съвет и може би код. Не ми се налага да използвам Перл, това сега е единичен случей.
Активен

prowler

  • Напреднали
  • *****
  • Публикации: 103
    • Профил
Помощ за perl
« Отговор #3 -: Aug 10, 2006, 15:37 »
Примерен код
open(ALERT, $file);
my @line = <ALERT>;

towa ti prochita faila s ime $file i imash pyrwiq red w $line[0]
tam ti e chisloto koeto ti e ot posledniq alert

Примерен код
if(int($line[0] * 10) <= int($temp * 10 - 5)) {
... prawish alert
}

prowerqwa dali prochetenoto chislo e po-golqma s 0.5

Примерен код
open(ALERT, "> $file");
print <ALERT> $temp;
close(ALERT);

towa ti zapiswa wyw faila promenliwata $temp

sglobi teq neshta i si gotow.. '<img'>
Активен

axelic

  • Участници
  • ***
  • Публикации: 9
    • Профил
Помощ за perl
« Отговор #4 -: Aug 24, 2006, 14:42 »
Здрасти, много благодаря за помоща!!!
Накрая "спастрих" и аз нещо. Работи безпроблемно. Обаче ми се струва малко тромавичко. Ако имаш идея как да стане по-леко, без обаче да се навреди на функционалитета, ще съм благодарско '<img'>

Примерен код

#!/usr/bin/perl

$file="test.txt";
$critical=27.0;
$string = `tail -1 tempdaemon.temp`;
($date,$time,$temp) = split(" ",$temp_a);
open ( INFILE, "<$file" ) or die "Can't open $file: $!\n";
@lines = <INFILE>;
close INFILE;
$null=0.0;

if ($temp_a>=$critical){
   open ( INFILE, "<$file" ) or die "Can't open $file: $!\n";
        if ($lines[0]!=0.0){
             $temp_t=$lines[0];
             if($temp_a>$temp_t){
                 if(($temp_a-$temp_t)>=0.5){
                      open (OUTFILE, ">$file" ) or die "Can't open $file: $!\n";
                      print OUTFILE "$temp_a\n";
                      print "Send note with temperatur: $temp_a\n";
                      close OUTFILE;
                 }
             }
             if($temp_a<$temp_t){
                 if(($temp_t-$temp_a)>=0.5){
                      open (OUTFILE, ">$file" ) or die "Can't open $file: $!\n";
                      print OUTFILE "$temp_a\n";
                      print "Send note with temperatur: $temp_a\n";
                      close OUTFILE;
                 }
             }
        }
        else{open (OUTFILE, ">$file" ) or die "Can't open $file: $!\n";
                      print OUTFILE "$temp_a\n";
                      print "Send note with temperatur: $temp_a\n";
                      close OUTFILE;
        }
   close INFILE;
}
if ($temp_a<$critical){
     open ( INFILE, "<$file" ) or die "Can't open $file: $!\n";
     if ($lines[0]!=0.0){
     print "Send note with temperatur: $temp_a\n";
     close INFILE;
     open (OUTFILE, ">$file" ) or die "Can't open $file: $!\n";
     print OUTFILE "$null\n";
     close OUTFILE;
     }
}




Активен

VladSun

  • Moderator
  • Напреднали
  • *****
  • Публикации: 2166
    • Профил
Помощ за perl
« Отговор #5 -: Aug 24, 2006, 18:58 »
Не съм чел подробно скрипта, но веднага ми прави впечатление, че отваряш и четеш (а понякога даже не четеш) един и същ файл по няколко пъти.
Имам чувството, че Copy-Paste-a здраво е действал тука '<img'>
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

axelic

  • Участници
  • ***
  • Публикации: 9
    • Профил
Помощ за perl
« Отговор #6 -: Aug 24, 2006, 19:44 »
Цитат (VladSun @ Авг. 24 2006,19:58)
Не съм чел подробно скрипта, но веднага ми прави впечатление, че отваряш и четеш (а понякога даже не четеш) един и същ файл по няколко пъти.
Имам чувството, че Copy-Paste-a здраво е действал тука '<img'>

Ами така е, но съм го направил съвсем целенасочено!
Както вече писах - нямам почти никакво понятие от Perl,
но успях някакси да го направя пустия му скрипт. Изхождам от знания които имам в други насоки, и не претендирам за "отлични постижения". Лесно е да съставиш алгоритъма, но е рудно да го имплементираш, без да имаш почти никакво понятие от особеностите на езика. Точно за това моля за помощ - за "фината настройка".  '<img'>
Активен

soulcollector

  • Напреднали
  • *****
  • Публикации: 54
    • Профил
Помощ за perl
« Отговор #7 -: Aug 25, 2006, 04:43 »
Ами всъщност този файл temp.lock се създава точно с тази цел - след като температурата е станала над 27 градуса, предупреждава и създава файла. Докато файлът съществува и температурата е над 27 няма нови съобщения. Ако температурата спадне и файлът съществува той се трие.
Неудобно в случая е, че всеки път преди да пуснеш daemon-а трябва да си сигурен, че НЕ съществува файл temp.lock

Примерен код

#!/usr/bin/perl

$critical = 27;
$lock = "temp.lock";

$string = `tail -1 tempdaemon.temp`;

($date,$time,$temp) = split / /, $string;

if ($temp >= "$critical" && !(-f $lock)) {
   print "Allert";
   system "/usr/bin/touch $lock";
}

if ($temp < "$critical" && -f $lock) {
   sytem "/bin/rm $lock";
}


Друг вариант е да не използваш такъв файл, а да четеш последните два реда от tempdaemon.temp и да вземеш двете температури. После сравняваш - Ако текущата е над или е 27, а предишната под 27 - ALERT. Т.е

Примерен код

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

my $critical = 27;

# четене на температурите - предполага се, че DATE TIME TEMP са разделени с
# един интервал и всеки ред в tempdaemon.temp e в този вид
my ($temp_b, $temp_n) = split /\n/, `tail -2 tempdaemon.temp | cut -d ' ' -f 3`;

if ($temp_n >= $critical && $temp_b < $critical) {
   print "ALERT\n"
}



PS. За да не стават такива грешки, като тази с $_lock вместо $lock във втория if твоят код е добре да се ползват use warnings; и use strict;
Активен

This place inside my brain
another kind of pain. (Korn)

axelic

  • Участници
  • ***
  • Публикации: 9
    • Профил
Помощ за perl
« Отговор #8 -: Aug 25, 2006, 13:13 »
Цитат (soulcollector @ Авг. 25 2006,05:43)

Здрасти, погледни моля те втория ми пост в тази тема - там кода е съвсем друг, а и вече функционира.
Активен

VladSun

  • Moderator
  • Напреднали
  • *****
  • Публикации: 2166
    • Профил
Помощ за perl
« Отговор #9 -: Aug 25, 2006, 18:31 »
Примерен код

#!/usr/bin/perl

$file = "test.txt";
$critical = 27.0;
$string=`tail -1 tempdaemon.temp`;
($date, $time, $temp_a) = split(" ", $string);

$last_temp = `cat $file`;
chomp($last_temp);

if ( ($temp_a >= $critical) and ($last_temp < $critical) )
{
    `echo $temp_a > $file`;
    print "Send note with temperatur: $temp_a\n";
}
else
{
    `echo $temp_a > $file`;
}



Това ми се струва, че отговаря на задачката макар, че вече стана по-лесно да го напишеш на bash script '<img'> .
Само не разбрах  - къде се използва temp.lock в твоя скрипт ( във втория пост ) и какво разбираш под предупреждение - само print "Bla bla" стига ли? '<img'>



Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

soulcollector

  • Напреднали
  • *****
  • Публикации: 54
    • Профил
Помощ за perl
« Отговор #10 -: Aug 26, 2006, 00:24 »
Точно този скрипт силно се съмнявам да работи. А ако наистина работи, бих искал да знам откъде се взима стойността на $temp_a още на ред 6?

Ето до какво го докарах

Примерен код

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

sub temp_warn ($$);

my $file = "test.txt";
my $critical = 27.0;

my $string = `tail -1 tempdaemon.temp`;

my ($date, $time, $temp) = split / /, $string;

open INFILE, "$file" or die "Can't open $file: $!\n";
my $temp_t = <INFILE>;
close INFILE;
chomp $temp_t;

if ($temp >= $critical and ($temp_t == 0.0 or abs ($temp - $temp_t) >= 0.5)) {
   temp_warn $file, $temp;
   print "Send note with temperature: $temp\n";
}

if ($temp < $critical and $temp != 0.0) {
   temp_warn $file, '0.0';
   print "Send note with temperature: $temp\n";
}

sub temp_warn ($$) {
   my $file = shift;
   my $temp = shift;

   open OUTFILE, "> $file" or die "Can't open file $file: $!\n";
   print OUTFILE "$temp\n";
   close OUTFILE;
}


Би могло да се сложи един return в края на блока на първият if с цел да се избегне излишната (в случая) проверка на втория if.



Активен

This place inside my brain
another kind of pain. (Korn)

VladSun

  • Moderator
  • Напреднали
  • *****
  • Публикации: 2166
    • Профил
Помощ за perl
« Отговор #11 -: Aug 26, 2006, 15:38 »
Прав си - просто модифицирах дадения вече скрипт и не съм гледал нагоре как се дава стойност на променливите.

Но ... кому е нужно толкова сложно да е всичко - няма нужда от Perl при условие, че половината от кода е bash команди?

Примерен код

#!/bin/bash

file="file.txt"
critical_temp=27
temp=$(tail -1 tempdaemon.temp | cut -s -d" " -f3)
last_temp = $(cat $file);

echo $temp > $file;

if [ "$temp" -gt "$critical_temp" ] && [ "$last_temp" -lt "$critical_temp" ];
then
   echo "Send note with temperature: $temp";
fi
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

axelic

  • Участници
  • ***
  • Публикации: 9
    • Профил
Помощ за perl
« Отговор #12 -: Aug 26, 2006, 16:39 »
Може би аз не съм се изразил ясно.
Всяка минута в tempdaemon.temp се записва актуалната температура - дата, час, температура(temp_a). Скрипта чете от него, и ако мине над 27 градуса,започва да изпраща съобщения с актуалната температура. Проблема е, че това означава всяка минута да се изпраща съобщение(а температурата не мърда много - с 0.1 градус на 30 минути), което е много досадно, а и скъпо - съобщенията са с SMS(т.е. между 27.0 и 27.2 обикновено минава 1 час, а се получават 60 SMS). Затова се взе решение да се праща съобщение на всеки 0.5 градуса, след като е минала критичната температура. т.е. ако предположим, че "входната" температура е 27.1, то първия SMS да е при нея (входната), а втория - или при 27.6, или ако падне под 27.0 градуса. Знам, че скрипта ми изобщо не е елегантен, но досега изобщо не бях правил каквото и да е на Perl.

Обяснението на моя вариант на скрипта е следното:
Всяка минута в tempdaemon.temp се записва новата актуална температура. Скрипта чете от него, и ако температурата скочи над 27 градуса:
1. проверява, дали във файла test.txt на първия ред стойността е 0.0, и ако е - праща съобщение, и записва актуалната температура на мястото на 0.0(примерно 27.1).
2. при следващата(след една минута) температура взета от tempdaemon.temp се проверява, дали е над 27 градуса, дали в test.txt стойността е различна от 0.0(а тя е, и в такъв случей дали е по-голяма от нея с поне 0.5 градуса. Ако да - праща съобщение, и записва новата на мястото на старата в test.txt. Ако не е по-голяма с поне 0.5 градуса, и стойността е различна от 0.0 - просто продължава нататък изпълнението на кода и не записва/праща нищо.
В моя пример - при записани последно 27.1 градуса в test.txt, да кажем, че температурата се покачва бавно, ще се изпрати съобщение едва когато разликата между актуалната и тази в test.txt стане равна или по-голяма от 0.5 градуса - сефте при минимум 27.6 '<img'> . Има ли пик - примерно била е 27.1 а след една минута се докладва, че е 28.5 - то това(28.5) ще стане актуалната записана в test.txt температура, и разбира се ще се изпрати съобщение.
Пада ли - по същия начин. Особеното е, че ако температурата падне под 27.0 градуса, то първо ще провери дали в test.txt стойността е 0.0, и ако не е (това означава, че преди една минута температурата е била над 27.0 градуса) ще изпрати съобщение със актуалната температура (примерно 26.9 - да спре да се шашка админа '<img'> ), и веднага след това ще запище в test.txt стойността 0.0.



Активен

VladSun

  • Moderator
  • Напреднали
  • *****
  • Публикации: 2166
    • Профил
Помощ за perl
« Отговор #13 -: Aug 26, 2006, 16:59 »
Примерен код

#!/bin/bash

file="file.txt"
critical_temp=27
treshold=0.5
temp=$(tail -1 tempdaemon.temp | cut -s -d" " -f3)
last_temp = $(cat $file);


if [ "$temp" -gt "$critical_temp" ];
then
   if [ "$last_temp" -lt "$critical_temp" ];
   then
      echo $temp > $file;
      echo "Send note with temperature: $temp";
   else
      delta=$(($temp - $last_temp))
      if [ "$delta" -gt "$treshold" ];
      then
        echo $temp > $file;
        echo "Send note with temperature: $temp";
      fi
   fi
else
   if [ "$last_temp" -gt "$critical_temp" ];
   then
      echo $temp > $file;
      echo "Send note with temperature: $temp";
   else
fi
Активен

KISS Principle ( Keep-It-Short-and-Simple )
http://openfmi.net/projects/flattc/
Има 10 вида хора на този свят - разбиращи двоичния код и тези, които не го разбират :P

soulcollector

  • Напреднали
  • *****
  • Публикации: 54
    • Профил
Помощ за perl
« Отговор #14 -: Aug 26, 2006, 23:19 »
Това би трябвало да правиш каквото искаш.
Примерен код

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

sub temp_warn ($$);

my $file = "test.txt";
my $critical = 27.0;

my $temp = `tail -1 tempdaemon.temp | cut -s -d ' ' -f 3`;

open INFILE, "$file" or die "Can't open $file: $!\n";
my $temp_t = <INFILE>;
close INFILE;
chomp $temp_t;

if ($temp >= $critical and ($temp_t == 0.0 or $temp - $temp_t >= 0.5)) {
        temp_warn $file, $temp;
        print "Send note with temperature: $temp\n";
}
if ($temp < $critical and $temp != 0.0) {
        temp_warn $file, '0.0';
        print "Send note with temperature: $temp\n";
}

sub temp_warn ($$) {
        my $file = shift;
        my $temp = shift;

        open OUTFILE, "> $file" or die "Can't open file $file: $!\n";
        print OUTFILE "$temp\n";
        close OUTFILE;
}



Но VladSun може и да е прав, че bash е по - добър избор, а и последният му скрипт ми изглежда еквивалентен.

Към VladSun: за инициализациите имах предвид точно скрипта, който си копирал.



Активен

This place inside my brain
another kind of pain. (Korn)

Подобни теми
Заглавие Започната от Отговора Прегледи Последна публикация
Perl
Общ форум
x11r6 5 3714 Последна публикация Aug 09, 2003, 10:03
от x11r6
Perl
Общ форум
Йордан 3 3126 Последна публикация Nov 13, 2003, 16:14
от Йордан
Gtk-Perl
Хардуерни и софтуерни проблеми
apogza 0 2013 Последна публикация Jan 24, 2004, 12:52
от apogza
Ползва ли се Perl в България и за какво?
Общ форум
berov 63 19579 Последна публикация Jan 31, 2005, 11:17
от toxigen
Четене от Серийни портове с Perl
Общ форум
berov 2 2848 Последна публикация Jun 15, 2004, 18:17
от berov