Reputation: 3
I've written a bash script to truncate through a server list and perform various commands. I would like to incorporate a progress indicator like a percent complete while the script is running. I found a script online to perform this but it's not working properly and I am unsure how to utilize it.
The dialog command is not an option here as I am working with nsh
#!/bin/bash
i=0
while [[ $i -lt 11 ]]; do
##
## \r = carriage return
## \c = suppress linefeed
##
echo -en "\r$i%\c\b"
(( i=i+1 ))
sleep 1
done
echo
exit 0
For testing purposes I am only connecting to each server and echoing the hostname.
for i in $(cat serverlist.txt)
do
nexec -i hostname
done
How can I utilize the first code snipped to show the progress while going through the list of servers in the code above?
Upvotes: 0
Views: 917
Reputation: 295480
write_status() {
done=0
total=$1
columns=${COLUMNS:-100}
# print initial, empty progress bar
for (( i=0; i<columns; i++ )); do printf '-'; done; printf '\r'
# every time we read a line, print a progress bar with one more item complete
while read -r; do
done=$(( done + 1 ))
pct=$(( done * columns / total ))
for ((i=0; i<pct; i++)); do
printf '+'
done
for ((i=pct; i<columns; i++)); do
printf '-'
done
printf '\r'
if (( done == total )); then break; fi
done
}
# read server names into an array; the below is bash 4.x syntax
readarray -t servers <serverlist.txt
# direct FD 4 to the a subshell running the write_status function
exec 4> >(write_status "${#servers[@]}")
for hostname in "${servers[@]}"; do
nexec -i "$hostname" # actually run the command
echo >&4 # ...and notify write_status that it completed
done
If you wanted to parallelize the remote commands, you can do that by replacing the for
loop at the bottom with the following:
for hostname in "${servers[@]}"; do
(nexec -i "$hostname"; echo >&4) &
done
wait
If your shell is a version of bash prior to 4.0, then the readarray -t servers <serverlist
can be replaced with the following:
servers=( )
while IFS= read -r server; do servers+=( "$server" ); done <serverlist.txt
Upvotes: 0
Reputation: 246847
To keep track of your progress, you'll want to store the list of servers in an array, so you know how many there are:
mapfile -t servers <serverlist.txt # servers is an array
n=${#servers[@]} # how many
i=0
for server in "${servers[@]}"; do
((i++))
progress=$(( i * 100 / n ))
nexec ...
echo "you are ${progress}% complete"
done
Upvotes: 1