hi, if you don't know what you are doing with Gtk2, you might want to look at the tk version, which uses more standard perl ipc.... see rsync with tk progressbar
The problem with rsync, as far as monitoring progress goes, is that it only returns a file name as it is complete..... it dosn't give the amount of realtime byte transfer..... so say you had 1 huge file and 99 little files to transfer...... if the first file being transferred is the big one..... you can get very erroneous progressbar info as the big file takes along time and no progress update is shown until it is done. The Tk script uses IPC::Open3 and you can truncate the script at the line $mw=tkinit, and run it without any gui..... get this to work, then add a gui
#!/usr/bin/perl
use warnings;
use strict;
use IPC::Open3;
$| = 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 (<DR>) { $last = $_; print; $count++ }
close DR;
my ($totsize) = $last =~ /^total size is (\d+)/;
print "$count\t$totsize\n";
or here is how to eliminate the corfirmation dialog......does this work ok for you?
You can remove the need for the start button if you want, but I recommend keeping the cancel button
#!/usr/bin/perl
use warnings;
use strict;
use Glib qw/TRUE FALSE/;
use Gtk2 '-init';
$| = 1;
my $srcdir = '/home/zentara/testdirout';
my $dstdir = '/home/zentara/testdirin';
my $cmd = "rsync -r -v $srcdir $dstdir";
#my $cmd = "rsync -r -v --bwlimit=500 $srcdir $dstdir";
my $pid;
#############################################################
#############################################################
my $window = Gtk2::Window->new('toplevel');
$window->set_title('Rsync-progressbar');
$window->signal_connect( 'destroy' => \&delete_event );
$window->set_border_width(10);
$window->set_size_request( 600, 300 );
my $vbox = Gtk2::VBox->new( FALSE, 6 );
$window->add($vbox);
$vbox->set_border_width(2);
my $hbox = Gtk2::HBox->new( FALSE, 6 );
$vbox->pack_end( $hbox, FALSE, FALSE, 0 );
$hbox->set_border_width(2);
$vbox->pack_end( Gtk2::HSeparator->new, FALSE, FALSE, 0 );
my $qbutton = Gtk2::Button->new_from_stock('gtk-quit');
$hbox->pack_end( $qbutton, FALSE, FALSE, 0 );
$qbutton->signal_connect( clicked => \&delete_event );
my $sbutton = Gtk2::Button->new('Start');
$hbox->pack_end( $sbutton, FALSE, FALSE, 0 );
$sbutton->signal_connect( clicked => \&start );
my $cbutton = Gtk2::Button->new('Cancel');
$hbox->pack_end( $cbutton, FALSE, FALSE, 0 );
$cbutton->signal_connect( clicked => sub {&killchd( $pid, 9 )
} );
my $scroll = Gtk2::ScrolledWindow->new;
my $textview = Gtk2::TextView->new;
$scroll->add($textview);
$vbox->pack_start( $scroll, TRUE, TRUE, 0 );
my $buffer = $textview->get_buffer;
my $end_mark = $buffer->create_mark( 'end', $buffer->get_end_iter, FAL
+SE );
# every time we insert text, scroll to that mark.
$buffer->signal_connect(
insert_text => sub {
$textview->scroll_to_mark( $end_mark, 0.0, TRUE, 0.0, 0.0 );
}
);
my $pbar = new Gtk2::ProgressBar;
$pbar->set_fraction(0);
$pbar->set_text("Ready to Start");
$hbox->pack_start( $pbar, TRUE, TRUE, 0 );
$window->show_all();
Gtk2->main;
#####################################
sub delete_event {
Gtk2->main_quit;
return FALSE;
}
###################################
sub init {
$pbar->set_text('Initializing file count');
#get a count of the files rysnc will transfer for progressbar
my ( $last, $count );
$pid = open( DR, " $cmd --dry-run |" ) or warn "$!\n";
while (<DR>) {
$last = $_;
$buffer->insert( $buffer->get_end_iter, $_ );
#gtk2 way of forcing update
Gtk2->main_iteration while Gtk2->events_pending;
$count++;
}
close DR;
my ($totsize) = $last =~ /^total size is (\d+)/;
$buffer->insert( $buffer->get_end_iter,
"filecount->$count\ttotal_bytes->$totsize\n" );
$pbar->set_text("$count files -- 0%");
return(0,0)
}
######################################
sub start {
$sbutton->set_sensitive(FALSE);
my ( $count, $totsize ) = &init;
if($count == 0){return}
my ( $counter, $percent );
$pid = open( RR, " $cmd |" ) or warn "$!\n";
while (<RR>) {
$buffer->insert( $buffer->get_end_iter, $_ );
$counter++;
$percent = ( $counter / $count );
$pbar->set_fraction($percent);
my $text = "$count files -- " . sprintf( '%2d', $percent * 100
+ ) . '%';
$pbar->set_text($text);
Gtk2->main_iteration while Gtk2->events_pending;
}
close RR;
}
##############################################################
sub killchd ($;$) {
$cbutton->set_sensitive(FALSE);
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__
|