0

EHLO!

This started like a "hey, give me 30 minutes" but here I am a day after. Basically what I want to do is to check "/var/log/messages" for 30 seconds and when someone plug-in a USB hard disk during that time, execute some commands.

So I am using Per function "File::Tail", and kinda works but I don't know how to run it for just 30 seconds, tail stays there until I manually exit( It works just as tail command). I been looking for solutions using fork but still no luck or experience on it. Part of the "tail" code is like this:

while ((defined($line=$file->read)) ) {

I appreciate any help or tip. If anyone has another solution using another, function or what ever, it's fine, I need the code for a "CGI".

Emel Ramone
  • 70
  • 1
  • 9
  • 3
    [`alarm`](http://perldoc.perl.org/functions/alarm.html)? – mob Oct 16 '16 at 02:08
  • 2
    `sleep(30);` before you call `$file->read` ;) – ikegami Oct 16 '16 at 05:50
  • 3
    F::T doesn't support that, so your options are: 1) Search for a module that does the same thing as F::T, but supports a timeout 2) Monkeypatch F::T 3) Reimplement F::T with the ability to time out, 4) `alarm` 5) Use a mechanism that doesn't involve `/var/log/messages` – ikegami Oct 16 '16 at 05:53
  • It seems unlikely that this code is going to work well in a CGI program. A CGI program a) runs (usually) on a remote server and b) will probably time out whilst waiting for the USB stick to be installed. Can you explain more about what you're actually trying to achieve here. I think you've gone off on the wrong track. – Dave Cross Oct 17 '16 at 09:06
  • An user should press a button to start and I will execute, an AGI for at least 30 seconds where I will tell him to connect the device and I will detect it – Emel Ramone Oct 18 '16 at 00:57

1 Answers1

1

You can achieve this using File::Tail::select().

The example below puts one seconds worth of the tailed file into the @pending array which is then processed. Looping 30 times will give you very close to 30 seconds (dependend on how active your /var/log/messages is). If you require more precise timing you can store the time before the loop and compare how long has passed on each iteration.

use File::Tail;
$file = File::Tail->new(name=>"/var/log/messages", interval=>1);

TIMER_LOOP:
while($t++ < 30){
    (undef,undef,@pending)=File::Tail::select(undef,undef,undef, 1, $file);
    for(@pending){
        if($_->read =~ /New USB device found/){
            print "Hello USB!\n";
            last TIMER_LOOP;
        }
    }
}
Finbar Crago
  • 432
  • 5
  • 12