Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?

Redirect dos console output to a widget

by Merrick (Initiate)
on Aug 22, 2001 at 23:06 UTC ( [id://107087] : perlquestion . print w/replies, xml ) Need Help??

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

I've been struggling with this issue for some time now. How can I redirect _all_ of the output from my perl programs into a text widget? From what I've read, I'll have to fork a separate widget child process, kill the dos parent process, pipe STDERR and/or STDOUT into the widget and update it frequently. Is there an easier way? Upon request, I'll provide samples of my poor attempts at scripting this. Pure and simple, the dos console is antiquated, anachronistic and unprofessional. Many thanks, Merrick
  • Comment on Redirect dos console output to a widget

Replies are listed 'Best First'.
Re: Redirect dos console output to a widget
by Rudif (Hermit) on Aug 23, 2001 at 03:16 UTC
    Er, please explain what do you mean by 'text widget'.
    A Win Edit Control in a Win application? An Edit control in Win32::GUI? A text widget in Perl/Tk? A text box in an HTML page? Or something else?
    I am missing something obvious?
(bbfu) (tied handles) Re: Redirect dos console output to a widget
by bbfu (Curate) on Aug 23, 2001 at 04:41 UTC

    You might try setting up a tied handle that would add anything sent to it to your widget, and then replacing STDOUT and STDERR with it. You'll probably have to use typeglob assignment to change STDOUT and STDERR, since I doubt the dup'ing form of open would work with tied handles... Not sure aboot that, though.


    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

      I don't think that would work. When the FD is grabbed from the handle, it will only be an OS file descriptor and won't know anything about the Perl layers. Now a pipe, being an OS construct, would do it.

      Have STDOUT and STDERR write to a pipe, and the GUI program reads from the other end and updates the widget.

      In Win32, pipes are not pseudoterminals and the program writing will know it's not the console and will buffer its output.


        one could, instead of using system, use fork/read/exec with a tied handle, which would allow perl constucts ... assuming the program to start was also perl. If the program is not perl, i agree with the pipe solution.
        can't sleep clowns will eat me
        -- MZSanford

        Um... It, uh, half works. :-)

        #!/usr/bin/perl use Tk; $mw = MainWindow->new(-name => 'Test', -title => 'Test'); $text = $mw->Text(); $text->pack(); tie *STDOUT, 'Text::Handle', $text; tie *STDERR, 'Text::Handle', $text; print "Hello\n"; print STDERR "Hi\n"; warn "Doesn't work! :(\n"; MainLoop; package Text::Handle; use Tie::Handle; @ISA = qw/Tie::StdHandle/; sub TIEHANDLE { my $class = shift; my $widget = shift; return bless \$widget, $class; } sub PRINT { my $self = shift; $$self->insert('end', join('',@_)); }

        Hrm. Looks like warn and die behave specially when it comes to STDERR. I can see good and bad points to that. :-/

        It would be nice to have it more "push" oriented so that you didn't have to poll pipes (either non-blockingly, or in a seperate thread/process) but it looks like you're still going to need warn and die %SIG handlers. But that's why I wrote Tk::Carp ;-)

        Seasons don't fear The Reaper.
        Nor do the wind, the sun, and the rain.
        We can be like they are.