This script is for monitoring the progress of a for loop that otherwise doesn't have any terminal output to tell you where your analysis is at.
- ThatLionLady's Loop-Progress
- Installation
- Requirements
- Usage
- Testing Testing 1, 2, 3
- Detailed Description
Clone it!
git clone https://github.com/ThatLionLady/loop-progress.git
cd loop-progress
chmod +x loop-progress.sh
ln -s loop-progress.sh /usr/local/bin/loop-progress #**Creating the symbolic link to your local bin may require superuser permission (ie use sudo).
loop-progress.shfrom this repository- a file with a list of what your for loop will run through (ex.
test.list) - your script with a for loop (ex.
test.sh)
The loop-progress script should be called twice within the your script.
(See Detailed Description for the explanation why.)
- outside the for loop calling your list
- inside the for loop calling x
Your very simplified script should look something like this:
#!/bin/sh
LIST=Path/to/Your.list
loop-progress ${LIST}
for THING in $(<${LIST}); do
command
loop-progress x
done
rm progress.tmpIf you want to see what it looks like before you commit to putting it into your own script:
- Run the
test.shscript from the loop-progress directory.- It should look like this:
This script should be called twice within the your script.
-
The first occurrence is outside the for loop calling your list.
-
This calls a function that starts by counting the number of items in your list and sets the initial progress number at that number.
- Your script:
#!/bin/sh LIST=Path/to/Your.list loop-progress ${LIST}
- This script:
function progress_from_count () { COUNT=$(cat ${LIST} | wc -l) PROGRESS=${COUNT} echo "PROGRESS=${PROGRESS}" > progress.tmp echo "COUNT=${COUNT}" >> progress.tmp echo -ne " (0% complete (${PROGRESS}/${COUNT} remaining): $(date +'%m/%d/%Y %r') \r" }
-
-
The second occurrence is inside the for loop calling "x".
-
This calls a function that starts by sourcing the progress number in a temporary file calculated during the previous call.
-
This will run through as part of your for loop until the progress reaches "0" and it congratulates you that your for loop is complete.
- Your script:
for THING in $(<${LIST}); do command loop-progress x done
- This script:
function progress_iteration () { source progress.tmp PROGRESS=$((${PROGRESS} - 1)) echo "PROGRESS=${PROGRESS}" > progress.tmp echo "COUNT=${COUNT}" >> progress.tmp PERCENT=$(echo "scale=4; (${COUNT} - ${PROGRESS}) / ${COUNT} * 100" | bc | cut -d . -f 1) if elif ... else echo -ne "CONGRATULATIONS! Your analysis finished at $(date +'%m/%d/%Y %r')" fi
-
The if elif else statement determines what to print in the terminal based on the calculated percentage completed. For example:
elif [ "${PERCENT}" -ge 20 ] && [ "${PERCENT}" -lt 30 ]; then
echo -ne "## (${PERCENT}% complete (${PROGRESS}/${COUNT} remaining): $(date +'%m/%d/%Y %r') \r"To break it down:
elif [ "${PERCENT}" -ge 20 ] && [ "${PERCENT}" -lt 30 ]; then= if the calculated percentage is greater than or equal to 20 and less than 30 (between 20 and 29.99...) thenecho -ne= print to the terminal without a trailing newline (a.k.a. a line break) while interpreting backslash-escaped characters"## ${PERCENT}% complete (${PROGRESS}/${COUNT} remaining): $(date +'%m/%d/%Y %r') \r"= what will be printed to the terminal##= progress bar${PERCENT}% complete= calculated percentage complete(${PROGRESS}/${COUNT} remaining)= calculated progress of total count remaining$(date +'%m/%d/%Y %r')= date in month/day/year format followed by 12-hour clock time\r= overwrite buffer with a carriage return- This (in combination with
-ne) is needed to overwrite the previously printed line and make the appearance of a progress bar.
- This (in combination with
To see the importance of the echo flags I used and have a better understanding if you want to make your own changes (e.g. if you want to keep when each loop is finished (i.e. no line replacement)):
-
removing
\rprints on one line like this:0% complete (26/26 remaining): 06/23/2022 11:46:49 PM 3% complete (25/26 remaining): 06/23/2022 11:46:50 PM 7% complete (24/26 remaining): 06/23/2022 11:46:51 PM # 11% complete (23/26 remaining): 06/23/2022 11:46:52 PM # 15% complete (22/26 remaining): 06/23/2022 11:46:53 PM -
removing the
nflag fromechoprints like this:0% complete (26/26 remaining): 06/23/2022 11:41:30 PM 3% complete (25/26 remaining): 06/23/2022 11:41:31 PM 7% complete (24/26 remaining): 06/23/2022 11:41:32 PM # 11% complete (23/26 remaining): 06/23/2022 11:41:33 PM # 15% complete (22/26 remaining): 06/23/2022 11:41:34 PM -
removing the
eflag fromechoprints on one line like this:0% complete (26/26 remaining): 06/23/2022 11:52:42 PM \r 3% complete (25/26 remaining): 06/23/2022 11:52:43 PM \r 7% complete (24/26 remaining): 06/23/2022 11:52:44 PM \r# 11% complete (23/26 remaining): 06/23/2022 11:52:45 PM \r# 15% complete (22/26 remaining): 06/23/2022 11:52:46 PM \r^ -
removing both
-nebut leaving\rprints like this:0% complete (26/26 remaining): 06/23/2022 11:54:00 PM \r 3% complete (25/26 remaining): 06/23/2022 11:54:01 PM \r 7% complete (24/26 remaining): 06/23/2022 11:54:02 PM \r # 11% complete (23/26 remaining): 06/23/2022 11:54:03 PM \r # 15% complete (22/26 remaining): 06/23/2022 11:54:04 PM \r -
removing
-neand\rprints like this:0% complete (26/26 remaining): 06/23/2022 11:55:53 PM 3% complete (25/26 remaining): 06/23/2022 11:55:54 PM 7% complete (24/26 remaining): 06/23/2022 11:55:55 PM # 11% complete (23/26 remaining): 06/23/2022 11:55:56 PM # 15% complete (22/26 remaining): 06/23/2022 11:55:57 PM
