I\'ve noticed that a lot of command line tools, wget for example, will show progress as a number or progress bar that advances as a process is completed. While the question isn\
Just print a CR (without a newline) to overwrite a line. Here is an example program in perl:
#!/usr/bin/env perl
$| = 1;
for (1..10) {
print "the count is: $_\r";
sleep(1)
}
I've also disabled output buffering ($| = 1
) so that the print command sends its output to the console immediately instead of buffering it.
Haskell example:
import System.IO
import Control.Monad
import Control.Concurrent
main = do
hSetBuffering stdout NoBuffering
forM_ [1..10] $ \i -> do
putStr $ "the count is: " ++ show i ++ "\r"
threadDelay 1000000
I can only speak about node.js, but the built-in readline module has some very basic screen handling functionality built-in. For example:
var readline = require('readline');
var c = 0;
var intvl = setInterval(function() {
// Clear entirety of current line
readline.clearLine(process.stdout, 0);
readline.cursorTo(process.stdout, 0);
process.stdout.write('Progress: ' + (++c) + '%');
if (c === 100)
clearInterval(intvl);
}, 500);
There are also third party modules if you want to get fancier, such as multimeter/meterbox and blessed/blessed-contrib.
Generally speaking though, some programs use ncurses, while others simply just manually output the ANSI escape codes to clear and redraw the current line.
They probably use the fancy ncurses library but on my Linux
for my personal command-line tools I simply send '\r'
to move the cursor back to the start of the line to overwrite it with new progress information.
#include <thread>
#include <chrono>
#include <iostream>
int main()
{
for(auto i = 0; i < 100; ++i)
{
std::cout << "\rprogress: " << i << "% " << std::flush;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
std::cout << "\rprogress: DONE " << std::flush;
}
Looking at GNU wget repo on GitHub -- progress.c
It seems they do it the same way i.e. print a \r
and then overwrite.
/* Print the contents of the buffer as a one-line ASCII "image" so
that it can be overwritten next time. */
static void
display_image (char *buf)
{
bool old = log_set_save_context (false);
logputs (LOG_VERBOSE, "\r");
logputs (LOG_VERBOSE, buf);
log_set_save_context (old);
}