#!/usr/bin/perl use warnings; use strict; use Tk; use Tk::ProgressBar; use IPC::Open3; use Proc::Killfam; $| = 1; my $srcdir = '/home/zentara/testdir_in'; my $dstdir = '/home/zentara/testdir_out'; my $cmd = "rsync -r -v $srcdir $dstdir"; #my $cmd = "rsync -r -v --bwlimit=10 $srcdir $dstdir"; #my $cmd = "rsync -r --dry-run --progress $srcdir $dstdir"; my $pid = open3( \*IN, \*OUT, 0, '/bin/sh' ); ############################################################# #get a count of the files rysnc will transfer for progressbar my $count = 0; my $counter = 0; my $percent = 0; my $last; my $pid1 = open( DR, " $cmd --dry-run |" ) or warn "$!\n"; while () { $last = $_; print; $count++ } close DR; my ($totsize) = $last =~ /^total size is (\d+)/; print "$count\t$totsize\n"; ############################################################# my $mw = tkinit; my $reader = $mw->fileevent( \*OUT, 'readable', \&get_out ); my $text = $mw->Scrolled( 'Text', -bg => 'black', -fg => 'lightsteelblue', -width => 80, -height => 5, -wrap => 'none' )->pack; my $frame = $mw->Frame( -background => 'grey40' ) ->pack( -fill => 'x' ); my $butgo; $butgo = $frame->Button( -text => 'Start', -command => sub { $butgo->configure( -state => 'disabled' ); print IN "$cmd\n"; } )->pack( -side => 'left', -padx => 20 ); my $butstop = $frame->Button( -text => 'Cancel', -command => sub { close OUT; &killchd( $pid, 9 ); } )->pack( -side => 'left', -padx => 20 ); my $butexit = $frame->Button( -text => 'Exit', -command => sub { exit; } )->pack( -side => 'left', -padx => 20 ); my $l1 = $frame->Label( -text => '%', -bg => 'black', -fg => 'green', )->pack( -side => 'right' ); my $l2 = $frame->Label( -textvariable => \$percent, -bg => 'black', -fg => 'green', -width => 3, )->pack( -side => 'right' ); my $pb = $frame->ProgressBar( -troughcolor => 'lightsteelblue', -fg => 'hotpink', -blocks => $count, -width => 20, -length => 200, -from => 0, -to => $count, -variable => \$counter, )->pack( -side => 'right', -padx => 20 ); MainLoop; ############################################################ sub get_out { my $texout = (); $text->insert( 'end', "$texout" ); $text->see('end'); $text->update; $counter++; $percent = sprintf( '%2d', ( ( $counter / $count ) * 100 ) ); } ############################################################## sub killchd ($;$) { require Proc::ProcessTable; my $sig = ( $_[1] =~ /^\-?\d+$/ ) ? $_[1] : 0; my $proc = Proc::ProcessTable->new; my %fields = map { $_ => 1 } $proc->fields; return undef unless exists $fields{'ppid'}; foreach ( @{ $proc->table } ) { kill $sig, $_->pid if ( $_->ppid == $_[0] ); } kill $sig, $_[0]; } __END__