Skip to content
Advertisement

Clear last two (and more) printed lines in Linux terminal emulator

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 "$SECONDSn$SECONDSn$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?

Advertisement

Answer

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("33[2A");  // This erases last two lines!
            sleep(1);
        }
    }
    return 0;
}
Advertisement