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.
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.
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
#!/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.
#!/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 : )
#!/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