简体   繁体   中英

Bash progress bar when running commands from within a script

I'm writing a bash script which performs an installation of stuff.

I don't want the user to see the commands and their output, so I'll redirect them using 2>&1 .

I do wish to print a progress bar for each section which finished installing, and a success/failed message according if there were errors, for example:

Installing OpenCv ..................... [Success]
Installing Qt     ..................... [Failed]

Here's my code:

#!/bin/bash

installOf="Installing OpenCv  "

function printProgressBar() 
{
    local progressBar="."
    printf "%s" "${progressBar}"
}

function InstEssent
{
    sudo apt-get -y install build-essential
    sleep 5
    echo "Done"
}

printf "%s" "${installOf}"

InstEssent  &

while [ "${InstEssent}" != "Done" ]
do
    printProgressBar 
    sleep 1
done

installStatus="Success"
printf " [%s]\n" "${installStatus}"

Well, as such there are no native tools in bash or other shells I can know of, but you can use this below printf & this custom function to achieve what you need. This small snippet will print the installation progress bar which you can print by just a normal function call printProgressBar at various places in the script where you would like to show it.

function printProgressBar() {
    local progressBar="."
    printf "%s" "${progressBar}"
}

Assuming you have n steps in your function call, insert this function call at places between. For the actual printing of error message, fill the installation header in variable installOf which assuming from your example could take either "Installing OpenCv " (or) "Installing Qt " , use it in this variable before the steps as

installOf="Installing OpenCv  "
printf "%s" "${installOf}"

and for the final status, since you didn't let us know how you get the overall status of the installation, assuming you find it depending upon success or failure, update it in another variable

installStatus="Success"
printf " [%s]\n" "${installStatus}"

So putting it all together, I have this simple while loop which runs the function for 20 calls, you can use a similar way to adopt your function call at various positions in your script.

installOf="Installing OpenCv  "

function printProgressBar() {
    local progressBar="."
    printf "%s" "${progressBar}"
}

printf "%s" "${installOf}"

while (( cnt < 20))
do
    ((cnt++))
    printProgressBar 
    sleep 1
done

# You can determine the status of your installation as your script demands

installStatus="Success"
printf " [%s]\n" "${installStatus}"

Running the script produces a result something similar to your requirement,

$ bash script.sh
Installing OpenCv  .................... [Success]

Observe that, each . represents each instance of a function call.

Update:-

Looking at your code logic, you are missing a point on how background jobs work. Your background function InstEssent in installing a certain module. To use the progress bar effectively, you need to constantly to poll the background job to see it is still running using the kill -0 "$pid" command and if it is running, print the install bar as indicated in the code below.

function InstEssent()
{
    sudo apt-get -y install build-essential
    sleep 5
}

printf "%s" "${installOf}"

InstEssent  &
pid_InstEssent="$!"

while kill -0 "$pid" 2> /dev/null
do
    printProgressBar 
    sleep 1
done

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM