#!/usr/bin/perl use strict; use warnings; use utf8; use Gtk2 '-init'; my $cmd='echo "Das ist nur ein Test!"'; my $pid=undef; my $window = Gtk2::Window->new( 'toplevel' ); $window->signal_connect (delete_event => sub{ exit(); }); my $box=Gtk2::VBox->new(); $window->add($box); my $frame = Gtk2::Frame->new( "Terminal" ); $frame->set_size_request (700, 400); $box->pack_start($frame, 1, 1, 5); my $term = shell_exec($cmd,$frame); my $cmd_txt=Gtk2::Entry->new(); $box->pack_start($cmd_txt, 0, 1, 5); my $btn=Gtk2::Button->new_with_label('AUSFÜHREN'); $btn->signal_connect('clicked' => sub{ shell_exec($cmd_txt->get_text(),\$term) } ); $box->pack_start($btn, 0, 1, 5); $window->show_all(); $SIG{CHLD}=sub{ exit() if(wait() == $pid); }; Gtk2->main(); # using '$pid'; sub shell_exec { my $cmd=shift; my $widget=shift; return unless($cmd); my $sock; my $parent; if(ref($widget) eq 'REF') { $sock=$$widget; $parent=$sock->parent(); } elsif($widget->isa('Gtk2::Socket')) { $sock=$widget; $parent=$sock->parent(); } elsif($widget->isa('Gtk2::Container')) { $parent=$widget; } if($pid) { __stop($pid); if($sock) { $parent->remove($sock) if($parent); $sock->destroy(); } } $sock = Gtk2::Socket->new(); if($parent) { $parent->add($sock); $parent->show_all(); $pid=__start($sock->get_id,$cmd); } $$widget=$sock if(ref($widget) eq 'REF'); return $sock; } sub __stop { my $pid=shift; return 1 unless($pid); local $SIG{CHLD}=sub{$pid=undef if(wait() == $pid)}; for my $v (15,15,15,9) { return 1 unless($pid && kill(0,$pid)); kill($v,$pid); sleep 1; } return 0; } sub __start { my $xid=shift; my $cmd=shift; my $pid=fork(); die() unless defined($pid); unless($pid) { exec('/usr/bin/rxvt', '-embed', $xid, '-e', 'sh', '-c', "$cmd; sh"); exit(); } return $pid; }