terrance has asked for the wisdom of the Perl Monks concerning the following question:

I'm working out this code but the output cannot print on the text area => "$txt1->insert('end', $_->{"input"}."(".localtime(time).") IP:$1 PORT:$2\n");" I had try on print the opening file's name, it work but start from the File::Tail::select it's not work. I think maybe it cannot display from a file handle. but how can i solve it?
#!/usr/local/bin/perl use Tk; use File::Tail; #Main Window my $mw = new MainWindow; $mw-> title ("Packet Analyzer Tool"); my $frm_1 = $mw -> Frame() -> pack(); my $frm_2 = $mw -> Frame() -> pack(); my $frm_3 = $mw -> Frame() -> pack(); my $frm_4 = $frm_3 -> Frame(-relief => 'groove', -borderwidth =>2) -> +pack(-side => "left"); my $frm_5 = $frm_3 -> Frame() -> pack(-side => "right",-after => $frm_ +4); my $but1 = $frm_1 -> Button(-text => "Start", -command =>\&push_start) -> pack(-side => "left", -anchor => 'nw', -ipadx => 30, -ipady + => 35); my $but2 = $frm_1 -> Button(-text => "Stop", -command =>\&push_stop) -> pack(-side => "left",-after =>$but1, -expand => 1,-ipadx => + 30, -ipady => 35); my $but3 = $frm_1 -> Button(-text => "Pause", -command =>\&push_pause) -> pack(-side => "left",-after => $but2 ,-ipadx => 30, -ipady +=> 35); #21 my $but4 = $frm_1 -> Button(-text => "Exit", -command =>\&push_exit) -> pack(-side => "left", -after => $but3 ,-ipadx => 30, -ipady + => 35); my $filter = $frm_2 ->Entry(-width => 65) -> pack(-side =>"left",-anch +or => 's'); my $but5 = $frm_2 -> Button(-text => "Search", -command =>\&push_searc +h) ->pack(-side => "left", -after => $filter, -ipadx => 10); my $txt1 = $frm_4 -> Text(-width => 60, -height =>20) -> pack(-side =>"left",-anchor => 's'); my $srl = $frm_4 -> Scrollbar(-orient=>'v', -command =>[yview => $txt] +); $txt1 -> configure(-yscrollcommand =>['set',$srl]); #tie *STDOUT, ref $txt1, $txt1; #print "Fed up\n"; #$txt1 -> insert('end', "XXX"); $txt1 -> grid(-row=>1, -column=>1); $srl -> grid(-row=>1, -column=>2,-sticky=>"ns"); my $txt2 = $frm_5 -> Text(-width => 15, -height =>20) -> pack(-side=>"right", -anchor => 'e'); MainLoop; #73 #Executed START BUTTON sub push_start { chdir( "/var/log/snort"); foreach my $fol(glob "*.*.*.*") { print "Opening $fol\n"; chdir("/var/log/snort/$fol"); foreach my $subfile(glob "*:*") { print "opening $subfile\n"; push(@files,File::Tail->new(name=>"$subfile",debug=>$debug +)); } while (1) { ($nfound,$timeleft,@pending)= File::Tail::select(undef,und +ef,undef,$timeout,@files); unless ($nfound) { print "Nothing to print \n"; } else { foreach(@pending) { my $line = $_->read; if ($line =~ /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d{1, +5} -> (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}):(\d{1,5})/) { $txt1->insert('end', $_->{"input"}."(".localtime(t +ime).") IP:$1 PORT:$2\n"); } } } } } }

Replies are listed 'Best First'.
Re: perl/tk: text output from tail function
by zentara (Cardinal) on Apr 05, 2011 at 14:20 UTC
    Your code is hard to read withall the regexes and everything, but this section is a real mess with Tk's eventloop,
    while (1) { ($nfound,$timeleft,@pending)= File::Tail::select(undef,und +ef,undef,$timeout,@files); unless ($nfound) { print "Nothing to print \n"; } else { foreach(@pending)
    You should use Tk's internal fileevent to watch tail's output, and never use while(1) loops in an eventloop system, like Tk.

    Here are a couple of Tk file tailing examples

    #!/usr/bin/perl use strict; use Tk; use IO::Handle; my $H=IO::Handle->new; open($H,"tail -f -n 50 z.txt |") or die $!; my $main = MainWindow->new; my $t = $main-> Scrolled('Text', -wrap=>'none')->pack(-expand=>1); $main->fileevent(\*$H,'readable',[\&fill,$t]); MainLoop; sub fill { my ($w) = @_; my $text; my $text =<$H>; $w->insert('end',$text); $w->yview('end'); }

    or

    #!/usr/bin/perl # tktail pathname use warnings; use strict; use Tk; my $pid = open(H, "tail -f -n 25 $ARGV[0]|") or die ; my $mw = MainWindow->new; my $t = $mw->Text(-width => 80, -height => 25, -wrap => 'none'); $t->pack(-expand => 1); $mw->fileevent('H', 'readable', [\&fill_text_widget, $t]); $mw->OnDestroy(\&quitCB); MainLoop; sub fill_text_widget { my($widget) = @_; my $text = <H>; $widget->insert('end', $text); $widget->yview('end'); } # end fill_text_widget sub quitCB { kill 9,$pid or die $!; exit; }

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
      I think your example only able read a single file in a time rite?But unable to read multi-file.
        I think your example only able read a single file in a time rite?But unable to read multi-file.

        Right. But, duh, how hard is it to to open several files for tail? I just showed you how to do one. There is no limit to how many fileevents you can setup, to watch as many files as you want. You THEN can write the output in different colors to the same text box, OR you can have each write to their own textbox.

        If you want automatic updates, setup Tk::repeat timers to refresh your text boxes with new tail output. Its all very straight forward, but a bit too big for me just to whip out off hand.

        C'mon.... you can do it... ;-)

        It's a sunny day, and I'm not a script writing service, unless you are a check-writing service :-)


        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh