cursor blinking removal in terminal, how to?

2019-02-03 17:32发布

问题:

I use the following lines to output my simulation's progress info in my c++ program,

double N=0;
double percent=0;
double total = 1000000;
for (int i; i<total; ++i)
{
    percent = 100*i/total;
    printf("\r[%6.4f%%]",percent);
}

It works fine!

But the problem is I see the terminal cursor keeps blinking cyclically through the numbers, this is very annoying, anyone knows how to get rid of this?

I've seen some programs like wget or ubuntu apt, they use progress bar or percentages too, but they seems no blinking cursor issue, I am wondering how did they do that?

Thanks!

回答1:

Just a guess: try to use a proper number of '\b' (backspace) characters instead of '\r'.

== EDIT ==

I'm not a Linux shell wizard, but this may work:

system("setterm -cursor off");
// ...display percentages...
system("setterm -cursor on");

Don't forget to #include <cstdlib> or <iostream>.



回答2:

You can hide and show the cursor using the DECTCEM (DEC text cursor enable mode) mode in DECSM and DECRM:

fputs("\e[?25l", stdout); /* hide the cursor */

fputs("\e[?25h", stdout); /* show the cursor */


回答3:

Those apps are probably using ncurses. See mvaddstr



回答4:

One way to avoid a blinking cursor is (as suggested) to hide the cursor temporarily.

However, that is only part of the solution. Your program should also take this into account:

  • after hiding the cursor and modifying the screen, before showing the cursor again move it back to the original location.
  • hiding/showing the cursor only keeps the cursor from noticeably blinking when your updates take only a small amount of time. If you happened to mix this with some time-consuming process, your cursor will blink.

The suggested solution using setterm is not portable; it is specific to the Linux console. And running an executable using system is not really necessary. But even running

system("tput civis");
...
system("tput cnorm");

is an improvement over using setterm.

Checking the source-code for wget doesn't find any cursor-hiding escape sequences. What you're seeing with its progress bar is that it leaves the cursor in roughly the same place whenever it does something time-consuming. The output to the terminal takes so little time that you do not notice the momentary rewrite of the line (by printing a carriage return, then writing most of the line over again). If it were slower, then hiding the cursor would help — up to a point.

By the way — this cursor-hiding technique is used in the terminal drivers for some editors (vim and vile).



回答5:

Press insert key...if that doesn't work then press the fn key in your keyboard. This will definitely work
Hope this helps



回答6:

The reason the cursor jumps around is because stdout is buffered, so you don't know actually how many characters are being printed at some point in time. The reason wget does not have a jumping cursor is that they are actually printing to stderr instead. Try the following:

fprintf(stderr,"\r[%6.4f%%]",percent);

This also has the advantage of not cluttering the file if you are saving the rest of the output somewhere using a pipe like:

$ ./executable > log.data