Search code examples
perlperltk

How to execute a system command and display its state in the Text Widget table


I tried to achieve above using the snippet from CPAN Tk::ExecuteCommand module but it gives me errors below when I execute any Perl program within the $ec->configure(-command section.

Also, the window will be closed unexpectedly once the Perl job completed. The script works and will not be closed if I just print the text instead of command within the entry (as the line I commented out). I choose to use this Cpan program as I wanted 2 things:

  1. To show the system command and run result within the text widget.
  2. To have the "execute button" turn to "cancel" when a job is running so that user could have chances to cancel an ongoing job.
    May I know how to achieve that?

Here is the error msg I get:

 > /usr/bin/perl: symbol lookup error: /usr/pkgs/perl/5.14.1/lib64/module/default/x86_64-linux/auto/Proc/ProcessTable/ProcessTable.so: undefined symbol: pthread_once

[13] Exit 127 test1.pl

And here is the code I used:

#!/usr/bin/perl

use Tk;
use Tk::ExecuteCommand;

$ec = tkinit()->ExecuteCommand(
     -command    => '',
     -entryWidth => 50,
     -height     => 10,
     -label      => '',
     -text       => 'Execute',
)->pack;
$ec->configure(-command => 'perl ./my_script.pl -wrapper wrapper_txt');
#$ec->configure(-command => 'Text line only');
$ec->execute_command;
$ec->update;

MainLoop;

Solution

  • Change $ec->configure(-command => 'perl ./my_script.pl -wrapper wrapper_txt'); to $ec->configure(-command => 'perl my_script.pl -wrapper wrapper_txt');

    and to get the status use a sub like below

    sub sys {
    
        # Execute a command asynchronously and return its status and output.
    
        my $cmd = shift;
    
        $ec->configure( -command => $cmd );
        my $t = $ec->Subwidget( 'text' ); # ROText widget
        $t->delete( '1.0' => 'end' );
        $ec->execute_command;
        return ($ec->get_status)[0], split /\n/, $t->get( '1.0' => 'end -1 chars' );
    
    } # end sys
    

    For killing it using a button, check the documentation, it says

    This ExecuteCommand mega widget is composed of an LabEntry widget for command entry, a "Do It" Button that initiates command execution, and a ROText widget that collects command execution output. While the command is executing, the "Do It" Button changes to a "Cancel" Button that can prematurely kill the executing command. The kill_command method does the same thing programmatically.

    So you need $exec->execute_command; $exec->get_status; and $exec->kill_command;.

    Edit: Looks like a known issue, try using latest version of Proc::ProcessTable.

    Also see: Bug #41397 for Proc-ProcessTable: Proc::ProcessTable - make test fails "undefined symbol: pthread_once"