http://www.perlmonks.org?node_id=652133

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

hello. i need to make an HTML with the progress output of a rsync command. i'm doing this:
open (CORE, "/usr/bin/rsync $rsyncOPT --progress $outbox $inbox |"); while (<CORE>) { # code }
but the problem is that the progress update sends \r and the loop doesn't see the line until it finish the transfer and sends a \n. i try:
local $/="\r";
but on small files never sends a \r because the transfer finish quickly. i need to have two $/. any ideas?

Replies are listed 'Best First'.
Re: parsing rsync output
by gamache (Friar) on Nov 21, 2007 at 14:21 UTC
    When you use \r, it must be in a double-quoted string; in a single-quoted (non-interpolated) string, it will literally be a backslash followed by lowercase r. (I don't know that this is your entire problem here, but it's worth a fix.)
      yes. i made an error in the post. sorry. i'm using double quotes.
Re: parsing rsync output
by jasonk (Parson) on Nov 22, 2007 at 02:51 UTC

    You've got a buffering problem. One option would be to set $/ to a reference to an integer, which will cause perl to give you a chunk of that many bytes on each read, rather than reading a line at a time. If you do this though, you then have to deal with assembling the records into lines yourself. Something like this should work...

    open ( CORE, "/usr/bin/rsync $rsyncOPT --progress $outbox $inbox |" ); local $/ = \128; # read 128 bytes at a time my $buffer = ''; while( <CORE> ) { $buffer .= $_; while ( $buffer =~ s/^(.*?)[\r\n]// ) { local $_ = $1; # code } }

    Another (possibly better) option would be to use Expect, which is designed for this type of application...


    We're not surrounded, we're in a target-rich environment!
      thanks i will look into Expext.