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

Hello,

I have the desire to print a multi-line status while a script is running. The script for example is a simple backup script.

My desire is to have something similar the following.

Script Started Start Checking/collecting info Please wait... Finished checking/collecting info. Backup Process Starting /etc/hosts <-- 10% (1/10) Complete -->
The line "/etc/hosts" would update with the different files/etc that is getting backed up but on the same line.
The line "<-- 10% (1/10) Complete -->" would be updated accordingly at the same time the previous line "/etc/hosts" is updated.

A single line is rather simple to do if I use the code below.

print "\e[K Something\r";
The problem I have here is I can't seem to get this to work without generating \n.
Any help would be greatly appreaciated.

TIA,
Lance

Replies are listed 'Best First'.
Re: Multi-line Status while script is running
by wind (Priest) on Mar 24, 2011 at 00:13 UTC

    I'm not positive, but I believe you'll need a cpan module like Curses

    Of course the easiest method is just to combine your dynamic text to a single line so that you can stick to just using \r

    my @dirs = map {chomp; $_} <DATA>; my $i = 0; my $lastlen = 0; local $| = 1; for my $dir (@dirs) { $i++; my $output = "<-- " . int($i / @dirs * 100) . " ($i/" . @dirs . ") + complete, $dir -->"; substr($output, 60) = '' if length $output > 60; # Truncate print "\r$output"; # Cover longer lines my $len = length $output; print ' ' x ($lastlen - $len) if $lastlen > $len; $lastlen = $len; sleep 1; } __DATA__ /etc/hosts /foo/bar /boo/bazinga /baz /foo/bin /foo/bin2 /foo/bin3 /foo/bin4 /foo/z /zar
      I have similar setup right now and when you get long lines like "/etc/sysconfig/network-scripts/ifcfg-bond0" plus the "<-- 90 (9/10) complete -->" it turn into a line that is too large for some terms and looks bad.

      Using "\e[K" seems to be better with my experience since there is no need to figure out the length of the previous output.

      my @dirs = map {chomp; $_} <DATA>; local $| = 1; my $i = 0; for my $dir (@dirs) { $i++; my $output = int($i / @dirs * 100) . "% ($i/" . @dirs . ")"; print "\e[K<-- $output complete, $dir -->\r"; sleep 1; } print "\n";
      The thing I think I haven't figured out with ncurses/term::cap/term::screen/etc is that I don't know how to determine the current line/row of the screen I am currently on. I can put text anyplace any want easily but can't get seem to understand how to determine the current line/row.

      Am I just missing the existing function to do that?