Cool Terminal Progress Bar – Python and Bash

Imagine you developed a script using python or bash that talks to the internet and fetch files or scrap data, etc, or simply take time to execute.

When you run that script you really don’t know if it is running or stuck or how long I have to wait. Right?

This will not be a problem if there’s a loading screen or a progress bar indicating the time remaining or the progress remaining using percentage. We can code the progress bar using both. In this tutorial, we will see how you can create progress bars in the terminal using Python and Bash.

Prerequisite

For this tutorial, we will be using Ubuntu for running our scripts. Ubuntu is Linux based operating system. In Ubuntu Python and bash are already installed, therefore is no need to install them again. Any debian-based operating systems will not have any problems following the tutorial.

If you are using the Windows operating system make sure you have python installed and have set the environment variables as you need to run the scripts from the terminal. If you also want to try bash on windows you’ll need WSL(Windows Subsystem for Linux).

Progress Bar using Python python3

Python is a high-level programming language. And can be used to achieve almost anything. There are many cool libraries present in python to create progress bars. In this tutorial we will see some of them:

1) TQDM

Tqdm is an easy-to-use library. It is especially for loops. It gives the progress meter for the loops. Simply 2 lines of code and you are done.

INSTALLATION

Hit the terminal and execute the following command :

❯ pip3 install tqdm

USAGE

Using tqdm is very simple just add it in your for loop like below :

from tqdm import tqdm
import time
for i in tqdm(range(20), desc = 'tqdm() Progress Bar'):
    time.sleep(0.1)
    # some tasks here
    # some more operations here

Here desc is one of many arguments that are used for the description of the progress bar. For example, when fetching a file it can be “downloading”.

OUTPUT

Tqdm can be used in many ways in your code. You should follow the official documentation for more snippets and features.

2) ALIVE_PROGRESS

Here’s another library for progress bars with a touch of cool animations. Alive_progress is simply amazing because here we have full control over the progress bar and also it can be set to dynamic. It is a lot better than tqdm because it has more features and we have different animations to choose from.

INSTALLATION

Hit the terminal and execute the following command :

❯ pip install alive-progress

USAGE

A sample code if you have a script that downloads files from the internet:

from alive_progress import alive_bar
import time

for i in range(3):
    with alive_bar(100, ctrl_c=False, title=f'Downloading {i}') as bar:
         for i in range(100):
             time.sleep(0.02)
             bar()

where 100 is the max length of progress. ctrl_c = False means CTRL + C will not work when the code within the progress bar is been executed(CTRL + C is used to terminate a task in a terminal). This can be especially used when an important task is being performed and you don’t want the user to terminate the task. By default it is True. And title is for the title for the progress bar.

OUTPUT

We can also change the theme of the progress bar like below:

from alive_progress import alive_bar
import time

for i in range(3):
    with alive_bar(100, ctrl_c=False, title=f'Downloading {i}', bar='halloween', spinner='twirls') as bar:
         for i in range(100):
             time.sleep(0.02)
             bar()

It also supports spinners.

OUTPUT

You can choose from many available themes and spinners. You can display them all at once and than choose what suits you the best :

from alive_progress.styles import showtime

showtime()

OUTPUT

Visit the github repository for more detailed information.

3. HALO

Halo is more of a spinner than a loading screen. It can be used when the operations require less time.

INSTALLATION

Hit the terminal and execute the following command :

❯ pip install halo

USAGE

from __future__ import unicode_literals
import os
import sys
import time

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from halo import Halo

success_message = 'Loading success'
failed_message = 'Loading failed'
unicorn_message = 'Loading unicorn'

spinner = Halo(text=success_message, spinner='dots')

try:
    spinner.start()
    time.sleep(1)
    spinner.succeed()
    spinner.start(failed_message)
    time.sleep(1)
    spinner.fail()
    spinner.start(unicorn_message)
    time.sleep(1)
    spinner.stop_and_persist(symbol='🦄'.encode('utf-8'), text=unicorn_message)
except (KeyboardInterrupt, SystemExit):
    spinner.stop()

OUTPUT

Have a look at the github repository for more info.

4) YASPIN

Yet another spinner library for your command-line application. In Yaspin we have a variety of options to choose from. It is suitable for operations that require more time than usual.

INSTALLATION

Hit the terminal and execute the following command:

❯ pip install yaspin

USAGE

import time
from random import randint
from yaspin import yaspin
from yaspin.spinners import Spinners

with yaspin(text="Loading", color="yellow") as spinner:
    time.sleep(1)  # time consuming code

    success = randint(0, 1)
    if success:
        spinner.ok("✅ ")
    else:
        spinner.fail("💥 ")
        
 
with yaspin(Spinners.earth, text="Earth") as sp:
    time.sleep(1)                # time consuming code

    # change spinner
    sp.spinner = Spinners.moon
    sp.text = "Moon"

    time.sleep(1)  
    

    
with yaspin(text="Colors!") as sp:
    # Support all basic termcolor text colors
    colors = ("red", "green", "yellow", "blue", "magenta", "cyan", "white")

    for color in colors:
        sp.color, sp.text = color, color
        time.sleep(0.5)

OUTPUT

Visit the official website here.


Progress Bar using Bash bash

Bash is basically a command language or a command-line interpreter for the GNU-based operating systems. It can be seen in Linux operating systems. It is not Linux. And Linux is a kernel. Bash is running on top of GNU-based operating systems. Examples: Debian.

Shell scripts are written to achieve a specific task like copying a large number of files to a folder or cloning a GitHub repository and installing all the dependencies inside it automatically. Showing a progress bar while operations are being performed in the background will be a cherry on the cake.

Let’s start by creating a shell file. eg : test.sh. I am using gedit text editor you can use one of your choices.

USAGE

Copy the following code for a simple progress bar

#!/bin/bash

bar='####################'
echo ""
for i in {1..20}; do
    echo -ne "\rDownloading  ${bar:0:$i}" 
    sleep .1                 
done
echo ""
echo ""
echo "This is a simple progress bar"

You can run the code using a terminal like:

❯ bash test.sh

OUTPUT

Here’s another example if you want an animated and colorful loading screen in the terminal.

#!/bin/bash

function pro {
    bar=''
    for (( x=50; x <= 100; x++ )); do
        sleep 0.05
        bar="${bar}="
        echo -ne "$bar ${x}%\r"
    done
    echo -e "\n"
}

function proo {
    barr=''
    for (( y=50; y <= 100; y++ )); do
        sleep 0.05
        barr="${barr} "

        echo -ne "\r"
        echo -ne "\e[43m$barr\e[0m"

        local left="$(( 100 - $y ))"
        printf " %${left}s"
        echo -n "${y}%"
    done
    echo -e "\n"
}

pro

echo ""
echo "This was a progress bar with percentage"
echo ""

proo
echo "This was a progress bar with color"

OUTPUT

If you want to integrate a progress bar in a GUI-based command-line application the following code may be suitable for you.

#!/bin/bash

seq 1 100|dialog --title "Downloading Files" --gauge "Please wait ..." 11 60 0
sleep 1

OUTPUT

It can also be modified to show a description of the operations and add an appropriate title:

#!/bin/bash

phasess=( 
    'Ready to perform operations...'
    'Performing some operations...'
    'Please wait ...'
    'almost there...'
)   

for i in $(seq 1 100); do  
    sleep 0.04

    if [ $i -eq 100 ]; then
        echo -e "XXX\n100\nDone!\nXXX"
    elif [ $(($i % 25)) -eq 0 ]; then
        let "phase = $i / 25"
        echo -e "XXX\n$i\n${phasess[phase]}\nXXX"
    else
        echo $i
    fi 
done | whiptail --title 'This is a GUI progress bar' --gauge "${phasess[0]}" 6 60 0

OUTPUT

Wrapping UP! waving emoji 3d

Now you can make your command line applications more user-friendly and flexible. Hope you found this tutorial helpful.


SUGGESTED ARTICLES