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

Hi Monks, I'm writing Perl/Tk GUI and I would need a text widget to act as a "shell". So can I use it as a STDIN/STDOUT for running commands from the GUI? Can you point me to a sample code? Any information or suggestion would be appreciated. Thanks, Miros

Replies are listed 'Best First'.
Re: perl/tk interactive text widget
by jdtoronto (Prior) on Jun 12, 2007 at 18:49 UTC
    Their was/is a module in the X11 namespace, something like TkPerlConsole that will do the job.

    Alternatively it is trivial to re-direct STDOUT (an example can be found in Tk::Stderr) to a text widget. From a text widget you can pass command lines with arguments back to the underlying shell.

    jdtoronto

Re: perl/tk interactive text widget
by zentara (Cardinal) on Jun 13, 2007 at 11:47 UTC
    Here is an idea where you use IPC::Open3 to run bash, then display the output in a ROText widget. It's not perfect, and needs a binding on the entry, so you don't need to keep pressing the Execute button. :-)
    #!/usr/bin/perl use warnings; use strict; use Tk; use IPC::Open3; require Tk::ROText; $|=1; my $mw = new MainWindow; my $entry=$mw->Entry(-width => 80)->pack; $mw->Button(-text => 'Execute', -command => \&send_to_shell)->pack; my $textwin =$mw->Scrolled('ROText', -width => 80, -bg =>'white', -height => 24, )->pack; $textwin->tagConfigure( 'err', -foreground => 'red' ); my $pid = open3( \*IN, \*OUT, \*ERR, '/bin/bash' ) or warn "$!\n"; $mw->fileevent( \*OUT, readable => \&read_stdout ); $mw->fileevent( \*ERR, readable => \&read_stderr ); MainLoop; sub read_stdout { if( sysread( OUT, my $buffer, 1024 ) > 0 ){ $textwin->insert( 'end', $buffer ); $textwin->see('end'); } } sub read_stderr { if( sysread(ERR, my $buffer, 1024 ) > 0 ){ $textwin->insert( 'end', $buffer, 'err' ); $textwin->see('end'); } } sub send_to_shell { my $cmd= $entry->get(); print IN "$cmd\n"; }

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum