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

So I have a program with a UI that I am writing. I have four button in my UI. Two of which call system commands, push the output to a file and finally display the text in the file in a scrolledwindow. The first button works flawlessly. The second works as far as calling the system command and pushes the output to a file but fails to display the text from the file in the scrolled window.

use strict; use warnings; use diagnostics; use Tk; use Data::Dumper; require Tk::Pane; my $mw = MainWindow->new( ); $mw->geometry("300x300"); $mw->title("Dummy"); $mw->protocol( WM_DELETE_WINDOW => \&ask, ); my $SixPairButton = $mw->Button( -text => "START", -command => \&sixpair, )->pack( -side => "top", -anchor => "nw", ); my $SixAdButton = $mw->Button( -text => "PAIR", -command => \&sixad, )->pack( -side => "top", -anchor => "nw", ); my $ClearButton = $mw->Button( -text => "CLEAR", -command => \&clear, )->pack( -side => "top", -anchor => "nw", ); my $QuitButton = $mw->Button( -text => "QUIT", -command => \&stopad, )->pack( -side => "top", -anchor => "nw", ); my $Pane = $mw->Scrolled( 'Text', Name => 'Display', -scrollbars => 'e', -relief => "sunken", -background => "WHITE" )->pack( -side => 'bottom', -fill => 'both', -padx => '5', ); my $Count = 0; sub warning { my $Tlw = $mw->Toplevel; $Tlw->title('Warning'); my $Label = $Tlw->Label( -text => 'Please connect controller before pa +iring.' )->pack( -side => 'top', -pady => '15' ); $Tlw->Button( -text => "OK", -command => sub { $Tlw->withdraw }, )->pack( -side => 'bottom +', -anchor => 'se', -padx => '5', -pady => '5' ); }; my @file1; my $OutFile1; sub sixpair { open $OutFile1, "+>", "tmp1", or die "Can't open file: $!"; my @sixpair = qw(sixpair >tmp1); my $OutPut1 = system( "@sixpair" ); @file1 = <$OutFile1>; for my $i ( @file1 ) { $Pane->insert("end", $i); } $Count = 1; close($OutFile1); return }; sub sixad { for my $t ( @file1 ) { if( $t =~ m/No controller found on USB busses./ ) { &warning; return } } if ( $Count gt 0 ) { open my $OutFile2, "+>", "tmp2", or die "Can't open file: $!"; my @sixad = qw(sixad --start 2>tmp2); my $OutPut2 = system( "@sixad" ); my @file2 = < $OutFile2 >; for my $n ( @file2 ) { print "$n"; $Pane->insert("end", $n); return; } close($OutFile2); return; } else { &warning; return; } }; sub ask { my $Tlw = $mw->Toplevel; $Tlw->title('Prompt'); my $Label = $Tlw->Label( -text => 'Are you sure?' )->pack( -side => 't +op', -pady => '15' ); $Tlw->Button( -text => "Quit", -command => \&stopad, )->pack( -side => 'left', -anchor => 'sw', -padx => '5', -pady => '5', ); $Tlw->Button( -text => "Cancel", -command => sub { $Tlw->withdraw }, )->pack( -side => 'right' +, -anchor => 'se', -padx => '5', -pady => '5' ); }; sub clear { $Pane->delete('0.1', 'end'); }; sub stopad { my @stopad = qw/sixad --stop/; system(@stopad); exit 0; }; sub counter { $Count = '1'; }; MainLoop; =pod ## If your Bluetooth disappears or stops working run hciconfig hci0 up hciconfig -a if [[ $(hciconfig -a | grep -o "DOWN") ]]; then echo -e "\nBluetooth is off.\nTurning it on now.\n"; hciconfig set up; else echo -e "\nBluetooth is already on.\n"; fi =cut


How can I fix this? Thank you!

Replies are listed 'Best First'.
Re: text from 2nd file not displaying in scrolledwindow
by wjw (Priest) on Feb 20, 2014 at 05:35 UTC
    I don't have sixpair on my system, so what I did was simply replace the line:

    my @sixpair = qw(sixpair >tmp1); with
    my @sixpair = qw(lsusb >tmp1);

    to see what would happen. The window successfully got the output of the lsusb cmd.
    I would check to see if your 'sixpair' system cmd is actually being called. I suspect it is failing, with the
    failure going to the terminal and never getting to your tmp1 file.
    That is what is happening to me anyway.
    Hope that is helpful...


    ...the majority is always wrong, and always the last to know about it...
    Insanity: Doing the same thing over and over again and expecting different results.
      I wonder if it is possible that sixad is not using stdout?

      Have you tried using the redirect "&2>1" instead of just ">"?
      Sort of a shot in the dark, but that is the only thing I can think of unless sixad is simply
      puking without any output at all...
      Redirect shortcuts

      Best of luck...
      Update:Should have gone to the main posting...then I would have seen that you are already successful... Glad you got it working!

      ...the majority is always wrong, and always the last to know about it...
      Insanity: Doing the same thing over and over again and expecting different results.
      Yeah that's exactly what I found out last night. I replaced the sixad --start command with ls and the program worked. I even tried ls --help to see if it was the switches i was using with sixad but that's not the case. For some reason sixad --start is not running. Why I have no freaking clue. Thank you.
Re: text from 2nd file not displaying in scrolledwindow
by zentara (Cardinal) on Feb 20, 2014 at 10:55 UTC
    Your code is very flawed for a Tk program. Tk runs on an event-loop, and everytime you do something to interfere with the smooth flowing of the event-loop, like run a while loop, sleep, or run a system command, the event-loop can't run.

    So, you need to rewrite your system commands to use a piped open, and then a fileevent on the file handle provided by the piped open. Look at this code-->tk-ps for an example. There are many Tk examples already on google for searching. Remember to use timers to repeat things, and generally use fileevent for remote file or socket operations. You can get away with a quick "my $data = system ("cat $file |"); but you are better off avoiding anything which interferes with the eventloop. Especially for reading sockets or pipes, when the file is coming in a piece at a time.

    For loading a simple file into Tk Text, google for perl tk open file for display as text. The code has all been posted before, so you may as well learn to search for it yourself. :-)

    I see you seem to be reading usb buses, which probably act like a socket. See Re: hanged In Tk-socket program for some code.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: text from 2nd file not displaying in scrolledwindow
by amboxer21 (Sexton) on Feb 20, 2014 at 01:41 UTC
    I can get it to work with a while loop and using a different system command. Which leads me to believe its the way i am formatting the system command. The way I am laing it out in the code.

    sub sixad { for my $t ( @file1 ) { if( $t =~ m/No controller found on USB busses./ ) { &warning; return } } if ( $Count gt 0 ) { open my $OutFile2, "+>", "tmp2", or die "Can't open file: $!"; my @sixad = qw(ls >tmp2); my $OutPut2 = system( "@sixad" ); my @file2 = <$OutFile2>; while( <@file2> ) { #for my $n ( @file2 ) { $Pane->insert("end", "$_". "\n"); #return; } close($OutFile2); return; } else { &warning; return; } };
      This works but only when i hit control + c in the terminal. Which gives control back to the parent window/process.

      sub sixad { for my $t ( @file1 ) { if( $t =~ m/No controller found on USB busses./ ) { &warning; return } } if ( $Count gt 0 ) { open my $OutFile2, "+>", "tmp2", or die "Can't open file: $!"; my @sixad = qq/'\/usr\/bin\/sixad --start 2>tmp2'/; print system qq( '@sixad' ); my @file2 = <$OutFile2>; while( <@file2> ) { $Pane->insert("end", $_); } return; close($OutFile2); } else { &warning; return; } };
Re: text from 2nd file not displaying in scrolledwindow
by amboxer21 (Sexton) on Feb 20, 2014 at 16:12 UTC
    This did the trick.

    my @sixad = qq/\/etc\/init.d\/sixad start >tmp2/; system( @sixad );


    Here is the updated code. I fixed it up a bit too.
    use strict; use warnings; use diagnostics; use Tk; use Data::Dumper; require Tk::Pane; my $mw = MainWindow->new( ); $| = 1; $mw->geometry("300x300"); $mw->title("TkSixa"); $mw->protocol( WM_DELETE_WINDOW => \&ask, ); my $SixPairButton = $mw->Button( -text => "START", -command => \&sixpair, )->pack( -side => "top", -anchor => "nw", ); my $SixAdButton = $mw->Button( -text => "PAIR", -command => [ \&sixad, ] )->pack( -side => "top", -anchor => "nw", ); my $ClearButton = $mw->Button( -text => "CLEAR", -command => \&clear, )->pack( -side => "top", -anchor => "nw", ); my $QuitButton = $mw->Button( -text => "QUIT", -command => \&stopad, )->pack( -side => "top", -anchor => "nw", ); my $Pane = $mw->Scrolled( 'Text', Name => 'Display', -scrollbars => 'e', -relief => "sunken", -background => "WHITE" )->pack( -side => 'bottom', -fill => 'both', -padx => '5', ); sub warning { my $Tlw = $mw->Toplevel; $Tlw->title('Warning'); my $Label = $Tlw->Label( -text => 'Please connect controller before pa +iring.' )->pack( -side => 'top', -pady => '15' ); $Tlw->Button( -text => "OK", -command => sub { $Tlw->withdraw }, )->pack( -side => 'bottom +', -anchor => 'se', -padx => '5', -pady => '5' ); }; my @file1; my $OutFile1; my $Count = 0; sub sixpair { open $OutFile1, "+<", "tmp1", or die "Can't open file: $!"; @file1 = (); my @sixpair = qw(sixpair >tmp1); system( "@sixpair" ); while ( <$OutFile1> ) { push(@file1, $_); $Pane->insert("end", $_); } $Count = 1; return close($OutFile1); }; sub sixad { for my $t ( @file1 ) { if( $t =~ m/No controller found on USB busses./ ) { &warning; $Count = 0; return } } if ( $Count gt 0 ) { open my $OutFile2, "+<", "tmp2", or die "Can't open file: $!"; my @sixad = qq/\/etc\/init.d\/sixad start >tmp2/; system( @sixad ); while( <$OutFile2> ) { $Pane->insert("end", $_); } return; close($OutFile2); } else { &warning; return; } }; sub ask { my $Tlw = $mw->Toplevel; $Tlw->title('Prompt'); my $Label = $Tlw->Label( -text => 'Are you sure?' )->pack( -side => 't +op', -pady => '15' ); $Tlw->Button( -text => "Quit", -command => \&stopad, )->pack( -side => 'left', -anchor => 'sw', -padx => '5', -pady => '5', ); $Tlw->Button( -text => "Cancel", -command => sub { $Tlw->withdraw }, )->pack( -side => 'right' +, -anchor => 'se', -padx => '5', -pady => '5' ); }; sub clear { $Pane->delete('0.1', 'end'); }; sub stopad { my @stopad = qw/sixad --stop/; system(@stopad); exit 0; }; sub counter { $Count = '1'; }; MainLoop; =pod ## If your Bluetooth disappears or stops working run hciconfig hci0 up hciconfig -a if [[ $(hciconfig -a | grep -o "DOWN") ]]; then echo -e "\nBluetooth is off.\nTurning it on now.\n"; hciconfig set up; else echo -e "\nBluetooth is already on.\n"; fi =cut