-1

I once saw a console app that visualized a progress of multiple downloads with multiple progressbars, each on its own line. I was curious how to do that, but I found only partial solutions. Here they are:

One progressbar is easy

It is easy to clear one line with "carriage return" and thus visualize one progress bar, as it is discussed e.g. in this question. Easy to use, also a lot of helper libraries exist.

"use ncurses"

Everybody says "use ncurses". But as far as I know every ncurses program must start with initscr() call, that really clears the whole screen. Your prompt is gone, your terminal history is gone. This is not what I want.

Use terminfo from ncurses

Use sc, ed and rc capabilities from terminfo, as ilustrates this Bash script (the script is taken from this question):

tput sc; while [ true ]; do tput ed; echo -e "$SECONDS\n$SECONDS\n$SECONDS"; sleep 1; tput rc; done

This works, but only in xterm. My urxvt term ignores it, same as e.g. terminator.

So what are other options?

  • 1
    Escape sequences perhaps http://tldp.org/HOWTO/Bash-Prompt-HOWTO/c327.html ? – Marged May 06 '18 at 16:31
  • urxvt implements the terminfo features mentioned (perhaps you're setting `TERM` to something unrelated to that terminal). – Thomas Dickey May 06 '18 at 17:13
  • @Marged Yes, thank you, that works. I posted my own answer with a code I tested, because your comment cannot be accepted as answer. If you post your own I will be happy to accept it! – Martin Jiřička May 06 '18 at 17:29
  • @ThomasDickey My TERM is "rxvt-unicode-256color", but even when I set it on "xterm" it does not work. Here is also said that it works only in Xterm: http://tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html – Martin Jiřička May 06 '18 at 17:31
  • Happy I sent you in the right direction. Let's take stick to your answer. – Marged May 06 '18 at 17:38

1 Answers1

0

As user @Marged rightly pointed out, ANSI escape sequences are the answer.

Here is the C code that works for me. Crucial is the line 19 which prints ANSI sequence that erases last two lines (number of lines is arbitrary, it is stated in the sequence):

#include <stdio.h>
#include <unistd.h>

void progressBar(int done, int total) {
    int i;
    printf("[");
    for (i=0; i<total; ++i) {
        printf((done < i) ? " " : "=");
    }
    printf("]\n");
}

int main() {
    int i;
    for (i=0; i<5; ++i) {
        progressBar(i, 4);
        progressBar(2*i, 8);
        if (i != 4) {
            printf("\033[2A");  // This erases last two lines!
            sleep(1);
        }
    }
    return 0;
}