How to animate the command line?

Command Line

Command Line Problem Overview


I have always wondered how people update a previous line in a command line. a great example of this is when using the wget command in linux. It creates an ASCII loading bar of sorts that looks like this:

> [======>                    ] 37%

and of course the loading bar moves and the percent changes, But it doesn't make a new line. I cannot figure out how to do this. Can someone point me in the right direction?

Command Line Solutions


Solution 1 - Command Line

One way to do this is to repeatedly update the line of text with the current progress. For example:

def status(percent):
    sys.stdout.write("%3d%%\r" % percent)
    sys.stdout.flush()

Note that I used sys.stdout.write instead of print (this is Python) because print automatically prints "\r\n" (carriage-return new-line) at the end of each line. I just want the carriage-return which returns the cursor to the start of the line. Also, the flush() is necessary because by default, sys.stdout only flushes its output after a newline (or after its buffer gets full).

Solution 2 - Command Line

There are two ways I know of to do this:

  • Use the backspace escape character ('\b') to erase your line
  • Use the curses package, if your programming language of choice has bindings for it.

And a Google revealed ANSI Escape Codes, which appear to be a good way. For reference, here is a function in C++ to do this:

void DrawProgressBar(int len, double percent) {
  cout << "\x1B[2K"; // Erase the entire current line.
  cout << "\x1B[0E"; // Move to the beginning of the current line.
  string progress;
  for (int i = 0; i < len; ++i) {
    if (i < static_cast<int>(len * percent)) {
      progress += "=";
    } else {
      progress += " ";
    }
  }
  cout << "[" << progress << "] " << (static_cast<int>(100 * percent)) << "%";
  flush(cout); // Required.
}

Solution 3 - Command Line

The secret is to print only \r instead of \n or \r\n at the and of the line.

\r is called carriage return and it moves the cursor at the start of the line

\n is called line feed and it moves the cursor on the next line In the console. If you only use \r you overwrite the previously written line. So first write a line like the following:

[          ]

then add a sign for each tick

\r[=         ]

\r[==        ]

...

\r[==========]

and so on. You can use 10 chars, each representing a 10%. Also, if you want to display a message when finished, don't forget to also add enough white chars so that you overwrite the previously written equal signs like so:

\r[done      ]

Solution 4 - Command Line

below is my answer,use the windows APIConsoles(Windows), coding of C.

/*
* file: ProgressBarConsole.cpp
* description: a console progress bar Demo
* author: lijian <[email protected]>
* version: 1.0
* date: 2012-12-06
*/
#include <stdio.h>
#include <windows.h>

HANDLE hOut;
CONSOLE_SCREEN_BUFFER_INFO bInfo;
char charProgress[80] = 
    {"================================================================"};
char spaceProgress = ' ';

/*
* show a progress in the [row] line
* row start from 0 to the end
*/
int ProgressBar(char *task, int row, int progress)
{
    char str[100];
    int len, barLen,progressLen;
    COORD crStart, crCurr;
    GetConsoleScreenBufferInfo(hOut, &bInfo);
    crCurr = bInfo.dwCursorPosition; //the old position
    len = bInfo.dwMaximumWindowSize.X;
    barLen = len - 17;//minus the extra char
    progressLen = (int)((progress/100.0)*barLen);
    crStart.X = 0;
    crStart.Y = row;
    
    sprintf(str,"%-10s[%-.*s>%*c]%3d%%", task,progressLen,charProgress, barLen-progressLen,spaceProgress,50);
#if 0 //use stdand libary
    SetConsoleCursorPosition(hOut, crStart);
    printf("%s\n", str);
#else
    WriteConsoleOutputCharacter(hOut, str, len,crStart,NULL);
#endif
    SetConsoleCursorPosition(hOut, crCurr);
    return 0;
}
int main(int argc, char* argv[])
{
    int i;
    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(hOut, &bInfo);

    for (i=0;i<100;i++)
    {
        ProgressBar("test", 0, i);
        Sleep(50);
    }
    
    return 0;
}

Solution 5 - Command Line

PowerShell has a Write-Progress cmdlet that creates an in-console progress bar that you can update and modify as your script runs.

Solution 6 - Command Line

Here is the answer for your question... (python)

def disp_status(timelapse, timeout):
  if timelapse and timeout:
     percent = 100 * (float(timelapse)/float(timeout))
     sys.stdout.write("progress : ["+"*"*int(percent)+" "*(100-int(percent-1))+"]"+str(percent)+" %")
     sys.stdout.flush()
     stdout.write("\r  \r")

Solution 7 - Command Line

As a follow up to Greg's answer, here is an extended version of his function that allows you to display multi-line messages; just pass in a list or tuple of the strings you want to display/refresh.

def status(msgs):
    assert isinstance(msgs, (list, tuple))

    sys.stdout.write(''.join(msg + '\n' for msg in msgs[:-1]) + msgs[-1] + ('\x1b[A' * (len(msgs) - 1)) + '\r')
    sys.stdout.flush()

Note: I have only tested this using a linux terminal, so your mileage may vary on Windows-based systems.

Solution 8 - Command Line

If your using a scripting language you could use the "tput cup" command to get this done... P.S. This is a Linux/Unix thing only as far as I know...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThe.Anti.9View Question on Stackoverflow
Solution 1 - Command LineGreg HewgillView Answer on Stackoverflow
Solution 2 - Command LinehazzenView Answer on Stackoverflow
Solution 3 - Command LineicenacView Answer on Stackoverflow
Solution 4 - Command LinehustljianView Answer on Stackoverflow
Solution 5 - Command LineSteven MurawskiView Answer on Stackoverflow
Solution 6 - Command LinenarenView Answer on Stackoverflow
Solution 7 - Command LineBlakerView Answer on Stackoverflow
Solution 8 - Command LineJustinView Answer on Stackoverflow