The sections below will cover the following:

Discuss the script
Demonstrate and discuss tracking processes
Demonstrate and discuss adding a spinner
Demonstrate and discuss tracking APIs
Demonstrate and discuss tracking installations across a cluster (under development)

When working for various companies I have used progress bars in development environments to let me know when things are ready. The modivation behind this webpage... You will find many examples of progress bars on the web, but only a few actually show you how to apply them. The sections below will illustrate some basic examples using the same script, but with some minor modifications. That way you can learn how to tweak the script to suit your needs. A brief description will be provided with each example. However, if you'd like a more in-depth explaination, then please refer to the videos.

pjkaza@pbar: ~

The below script is used to determine when 15 containers have started. At a high-level the way it works:
The ProgressBar function contains mathimatical formulas used to determine percentage as well as printf statements that enable us to see it. The script my-topology.yml as argument to the command docker-topo --create is configured to spin up 15 docker containers and the docker ps -q | wc -l command output will provide us with the number of running containers. This value is stored in the _current variable and is fed to the function from the while loop, which is used to determine a point in time progress of the overall task. This will occur every second so long as the value is less than 15.

#!/bin/bash
# Author: Philip J. Kazanjian * Boston MA * 07/31/2020 *
# Src: * http://thekettlemaker.com/progressbar.html * https://github.com/PKazanjian/progressbar *
# Desc: A progressbar used to track the process of 15 containers starting
# Ack: ProgressBar function, fork of Teddy Skarin * https://github.com/fearside/ProgressBar/ *
#
_f100=15
_current=0
echo ""
printf '\e[1;34m%-6s\e[m' "Spawning Containers"
echo "
"
tput civis
stty -echo
CleanUp () {
   tput cnorm
   stty echo
}
trap CleanUp EXIT
docker-topo --create my-topology.yml > /dev/null 2>&1 &
ProgressBar () {
    _percent=$(("${1}*100/${_f100}*100"/100))
    _progress=$(("${_percent}*4"/10))
    _remainder=$((40-_progress))
    _completed=$(printf "%${_progress}s")
    _left=$(printf "%${_remainder}s")
    printf "\rProgress : [${_completed// /#}${_left// /-}] ${_percent}%%"
}
while [ "${_current}" -lt "${_f100}" ]
do
    sleep 1
    _current=$(docker ps -q | wc -l)
    ProgressBar "${_current}"
done
echo "
"
printf '\e[0;32m%-6s\e[m' "$(tput bold)Containers are Ready!!"
echo "
"
# EOF

Below we will add a spinner to let us know that the systems is working on it.

pjkaza@pbar: ~

At a high-level the way it works and how we will adjust our bash script:
These nested variables ${_spin:i++%${#_spin}:1} work together to iterate through the string "/-\|" and attain the value of it's current position each time the progress bar is printed. Below we will adjust our bash script for testing our spinner by setting _current equal to a value attained from a local track file. That way we can control the progress. With this setup, it is useful to use two terminals: one to redirect lines into the file and the other to edit and run the script (refer to the section video at the top of the page).

#!/bin/bash
# Author: Philip J. Kazanjian * Boston MA * 07/31/2020 *
# Src: * http://thekettlemaker.com/progressbar.html * https://github.com/PKazanjian/progressbar *
# Desc: A script used for developing progressbars
# Ack: ProgressBar function, fork of Teddy Skarin * https://github.com/fearside/ProgressBar/ *
#
_f100=15
_current=0
_spin="/-\|"
i=0
echo ""
printf '\e[1;34m%-6s\e[m' "Spawning Containers"
echo "
"
tput civis
stty -echo
touch count
CleanUp () {
   tput cnorm
   stty echo
   rm count
}
trap CleanUp EXIT
ProgressBar () {
    _percent=$(("${1}*100/${_f100}*100"/100))
    _progress=$(("${_percent}*4"/10))
    _remainder=$((40-_progress))
    _completed=$(printf "%${_progress}s")
    _left=$(printf "%${_remainder}s")
    printf "\rProgress : [${_completed// /#}${_spin:i++%${#_spin}:1}${_left// /-}] ${_percent}%%"
}
while [ "${_current}" -lt "${_f100}" ]
do
    sleep 1
    _current=$(wc -l < count)
    if [ "${_current}" = "${_f100}" ]
     then
      _spin="#"
    fi
    ProgressBar "${_current}"
done
echo "
"
printf '\e[0;32m%-6s\e[m' "$(tput bold)Containers are Ready!!"
echo "
"
# EOF

Next let's change the spinner and tweak the color to make it pop! Below are a couple hyperlinks in case you'd like to use a different spinner:

Brain Downs
Francois-Guillaume Ribreau

pjkaza@pbar: ~
#!/bin/bash
# Author: Philip J. Kazanjian * Boston MA * 07/31/2020 *
# Src: * http://thekettlemaker.com/progressbar.html * https://github.com/PKazanjian/progressbar *
# Desc: A script used for developing progressbars
# Ack: ProgressBar function, fork of Teddy Skarin * https://github.com/fearside/ProgressBar/ *
#
_f100=15
_current=0 i=0
_spin="⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
declare a b
echo ""
printf '\e[1;34m%-6s\e[m' "Spawning Containers"
echo "
"
tput civis
stty -echo
touch count
CleanUp () {
   tput cnorm
   stty echo
   rm count
}
trap CleanUp EXIT
ProgressBar () {
   _percent=$(("${1}*100/${_f100}*100"/100))
   _progress=$(("${_percent}*4"/10))
   _remainder=$((40-_progress))
   _completed=$(printf "%${_progress}s")
   _left=$(printf "%${_remainder}s")
   printf "\rProgress : [\e[42m\e[30m${_completed// /#}\e[0m${a}${_spin:i++%${#_spin}:1}${b}${_left// /-}] ${_percent}%%"
}
while [ "${_current}" -lt "${_f100}" ]
do
   sleep 1
   _current=$(wc -l < count)
    if [ "${_current}" = "${_f100}" ]
      then
       _spin="#"
       a="\e[42m\e[30m"
       b="\e[0m"   
    fi
      ProgressBar "${_current}"
done
echo "
"
printf '\e[0;32m%-6s\e[m' "$(tput bold)Containers are Ready!!"
echo "
"
# EOF

APIs within containers can take a considerable time longer before they can receive commands. In this example, it took an additional ten minutes after the 22 containers had started. Because it takes so long, we are going to include measuring when the containers start as well. For the APIs, we will count the number of "success" messages provided by ansible and store the added value within the _current variable. In the example, 100% consists of 22 running containers and 17 available APIs.

pjkaza@pbar: ~
#!/bin/bash
# Author: Philip J. Kazanjian * Boston MA * 08/21/2020 *
# Src: * http://thekettlemaker.com/progressbar.html * https://github.com/PKazanjian/progressbar *
# Desc: A progressbar used to track the progress of 22 containers starting and when 17 APIs are ready
# Ack: ProgressBar function, fork of Teddy Skarin * https://github.com/fearside/ProgressBar/ *
#
_f100=39
_current=0 i=0 j=0 k=0 x=75 y=22 z=5
_spin="┤┘┴└├┌┬┐"
declare a b
echo ""
printf '\e[1;34m%-6s\e[m' "Spawning Containers"
echo "
"
tput civis
stty -echo
touch /tmp/count
CleanUp () {
   tput cnorm
   stty echo
   rm /tmp/count
}
trap CleanUp EXIT
docker-topo --create bch-topology.yml > /dev/null 2>&1 &
ProgressBar () {
   _percent=$(("${1}*100/${_f100}*100"/100))
   _progress=$(("${_percent}*4"/10))
   _remainder=$((40-_progress))
   _completed=$(printf "%${_progress}s")
   _left=$(printf "%${_remainder}s")
   printf "\rProgress : [\e[42m\e[30m${_completed// /▒}\e[0m${a}${_spin:i++%${#_spin}:1}${b}${_left// /=}] ${_percent}%%"
}
while [ "${_current}" -lt "${_f100}" ]
do
   if [ "${_current}" -lt "$y" ]; then
      if [ "$k" -lt "$z" ]; then
         k=$((k+1))
      fi
      if [ "$k" = "$z" ]; then
         _containers=$(docker ps -q | wc -l)
         k=$((k=0))
      fi
   fi
   if [ "${_current}" -ge "$y" ]; then
      if [ "$j" = "$x" ]; then
         ansible -m eos_command -a "commands='show lldp neighbors' provider='{{ eos_connection }}'" all | grep -ic success >> /tmp/count &
         j=$((j=0))
      fi
      if [ "$j" -lt "$x" ]; then
         j=$((j+1))
         _apis=$(tail -n 1 /tmp/count)
      fi
   fi
     sleep 0.75
     _current=$((_containers + _apis))
   if [ "${_current}" = "${_f100}" ]; then
       _spin="▒"
       a="\e[42m\e[30m"
       b="\e[0m"
   fi
     ProgressBar "${_current}"
done
echo "
"
printf '\e[0;32m%-6s\e[m' "$(tput bold)APIs are Ready!!"
echo "
"
# EOF

This is still under development!!
Here I wanted to challange myself a bit by tracking intstallations & configuration across a cluster. Below I have successfully redirected stdout from all remove hosts to a local track file and tracked the installation progress based on the output that would usually be displayed within the terminal. This was done in parallel and is successful!!! Next I will use dd, du, or tar to track bytes... Once finished I will publish results here and on github : )

pjkaza@pbar: ~
#!/bin/bash
# Author: Philip J. Kazanjian * Boston MA * 08/10/2020 * Version 1 *
# Src: * http://thekettlemaker.com/progressbar.html * https://github.com/PKazanjian/trackinstallation  no repo yet :) *
# Ack: ProgressBar function, fork of Teddy Skarin * https://github.com/fearside/ProgressBar/ *
#
_f100=153
_current=0 i=0
_spin=".oO°Oo."
declare a b
echo ""
printf '\e[1;34m%-6s\e[m' "Provisioning Hadoop"
echo "
"
tput civis
stty -echo
CleanUp () {
   tput cnorm
   stty echo
}
trap CleanUp EXIT
ProgressBar () {
   _percent=$(("${1}*100/${_f100}*100"/100))
   _progress=$(("${_percent}*4"/10))
   _remainder=$((40-_progress))
   _completed=$(printf "%${_progress}s")
   _left=$(printf "%${_remainder}s")
   printf "\rProgress : [\e[42m\e[30m${_completed// /#}\e[0m${a}${_spin:i++%${#_spin}:1}${b}${_left// /=}] ${_percent}%%"
}
while [ "${_current}" -lt "${_f100}" ]
do
    sshpass -p 'P@ssw0rd' ssh -qo StrictHostKeyChecking=no support@master 'bash -s' < NN1 >> count &
    sshpass -p 'P@ssw0rd' ssh -qo StrictHostKeyChecking=no support@master2 'bash -s' < NN2 >> count &
    sshpass -p 'P@ssw0rd' ssh -qo StrictHostKeyChecking=no support@slave1 'bash -s' < DN1 >> count &
    sshpass -p 'P@ssw0rd' ssh -qo StrictHostKeyChecking=no support@slave2 'bash -s' < DN2 >> count &
    sleep 0.1
    _current=$(wc -l < count)
    if [ "${_current}" = "${_f100}" ] 
    then
      _spin="#"
      a="\e[42m\e[30m"
      b="\e[0m"
    fi
    ProgressBar "${_current}"
done
echo "
"
printf '\e[0;32m%-6s\e[m' "$(tput bold)Cluster Provisioned!!"
echo "
"
# EOF