Dori Dori -4 years ago 161
Linux Question

Linux terminal: carriage return stuck at line wrap

I have c++ code running on a remote Linux server, accessed via MobaXterm. The process takes a while and is multithreaded, so I've added a progress printing mechanism that looks like this:

void update_progress() {
omp_set_lock(&lock);
string progress = get_threads_progress();
cout << "\rProgress " << progress;
omp_unset_lock(&lock);
}


With three threads, it could look something like this:

Progress | 23/100 | 42/100 | 89/200


The carriage return is there so I can see the job's progress on a single line. The problems start when running my code on a 48-core machine: the progress
string is too long for the terminal, the line wraps around and the carriage return only sets the cursor back to the beginning of the current line. For example:

// Several threads run this in parallel
for (int i=1; i<=5; ++i) {
update_progress();
}


I'll get something like the following output:

Progress | 23/100 | 41/100 | 86/100 | 19/100 | 3/100 | 97/100 | 54/1
Progress | 23/100 | 42/100 | 86/100 | 19/100 | 3/100 | 97/100 | 54/1
Progress | 23/100 | 42/100 | 86/100 | 20/100 | 3/100 | 97/100 | 54/1
Progress | 23/100 | 42/100 | 87/100 | 20/100 | 3/100 | 97/100 | 54/1
00 | 23/100 | 21/100


I was under the assumption that the carriage return
\r
should successfully place the cursor back at the
P
in
Progress
, regardless of the terminal width...

Am I wrong? If so, how (if possible) can I get what I want? If not, what's the issue?

Answer Source

The carriage-return is not handled in your program or by the standard library, but by the terminal program that displays the text. And it only goes to the beginning of the current line, the line on which the cursor currently is, which if there is a wrap is not the start of the previous line. So make sure the text you print is simply not long enough to cause wrapping.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download