Last active
April 6, 2023 18:33
-
-
Save StrangeRanger/12e9b8292dc0d499a4fea42fdda93c03 to your computer and use it in GitHub Desktop.
spinning-waiting-stick.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# | |
# Provides two different methods that can be used to display a spinning stick that will | |
# continue to spin until a specific process is finished running. | |
# | |
# NOTE: 'method_two' is notiblely faster than 'method_one'. Despite this, it does not | |
# speak for the method's actual speed. That is dependent on how you use and | |
# implement the methods. For the case of the examples that I provided, 'method_one' | |
# is slower because I have it check if the incremented number is greater than or | |
# equal to the specified stopping number, for every iteration of the for loop. | |
# Though this might be obvious, checking during every iteration is not efficient | |
# and should not be implemented in an actual program, unelss you have a good | |
# reason. The only reason that I have 'method_one' do this, is because it allows | |
# me to provide a simple example of situations in which either method could be | |
# used. | |
# | |
######################################################################################## | |
#### [ Variables ] | |
## Change the color of the output text. | |
green="$(printf '\033[0;32m')" | |
blue="$(printf '\033[0;34m')" | |
nc="$(printf '\033[0m')" | |
clrln="$(printf '\r\033[K')" | |
#### End of [ Variables ] | |
######################################################################################## | |
#### [ Functions ] | |
#### Below are the two different methods (that I personally use) that can be used to | |
#### display a spinning stick. | |
######################################################################################## | |
#### [[ method_one ]] | |
#### Using 'method_one' is ideal in all situations, with an exception of one. In a | |
#### situation where a variable is modified with the intent to be used later in the | |
#### code, 'method_two' is much more ideal. The reason for this is because when a | |
#### variable is modified orcreated inside of a subprocess/subshell, the changes to that | |
#### variable will be lost once the subprocess exits. For more information, refer to the | |
#### following link: https://github.com/koalaman/shellcheck/wiki/SC2031 | |
method_one() { | |
# Variable to be incremented. | |
local var=0 | |
# The integer to stop itterating at. | |
local stop_at=1000000 | |
#### | |
# Function Info: Until a specified process is finished running, a spinning stick | |
# will output to the terminal, in place. | |
# | |
# Parameters: | |
# $1 - required | |
# Process ID of some command/function. | |
#### | |
waiting() { | |
local spin="-\|/" | |
local i=0 | |
## If the process $1 exists, continuously output a new character inside of $spin | |
## to create the illusion of a spinning stick. | |
while ps -p "$1" &>/dev/null; do | |
i=$(( (i+1) %4 )) | |
# NOTE: Here is a labeled version, describing how the below variable | |
# expansion works: '${parameter:offset:length} -> ${spin:$i:1}' | |
# You can find more information at the following link: | |
# https://mywiki.wooledge.org/BashGuide/Parameters#Parameter_Expansion | |
printf "%sPerforming action: %s" "$clrln" "${spin:$i:1}" | |
sleep .1 | |
done | |
} | |
## Recursively store the new value of $i, into $var. | |
## NOTE: This for statement is executed as a background process. | |
## NOTE 2: This for statement represents the actions to be performed and waited | |
## upon. | |
for ((i = 0; i < (stop_at + 1); i++)); do | |
var="$i" | |
## Once $i is greater than or equal to the value of $stop_at, output the value | |
## of $var. | |
if ((i >= stop_at)); then | |
# Output the new value of $var. | |
printf "%sOutput of 'var': %s\n" "$clrln" "${green}${var}${nc}" | |
fi | |
done & | |
# Execute the 'waiting' method, passing along the Process ID of the for statement. | |
waiting "$!" | |
echo -e "${green}==>${nc} Done with 'method_one'\n" | |
} | |
### End of [[ method_one ]] | |
######################################################################################## | |
#### [[ method_two ]] | |
#### As mentioned in the description of 'method_one', 'method_two' is ideal in | |
#### situations were a variable is being modified with the intent of being used later in | |
#### the code. | |
method_two() { | |
# Variable to be incremented. | |
local var=0 | |
#### | |
# Function Info: Until a specified process is finished running, a spinning stick | |
# will output to the terminal, in place. | |
#### | |
waiting() { | |
local spin="-\|/" | |
local i=0 | |
## While true, continuously output a new character inside of $spin to create the | |
## illusion of a spinning stick. | |
while true; do | |
i=$(( (i+1) %4 )) | |
# NOTE: Here is a labeled version, describing how the below variable | |
# expansion works: '${parameter:offset:length} -> ${spin:$i:1}' | |
# You can find more information at the following link: | |
# https://mywiki.wooledge.org/BashGuide/Parameters#Parameter_Expansion | |
printf "%sPerforming action: %s" "$clrln" "${spin:$i:1}" | |
sleep .1 | |
done | |
} | |
# Execute the 'waiting' method as a background process. | |
waiting & | |
# Save the Process ID of the executed function ('waiting'). | |
local _PID=$! | |
## Recursively store the new value of $i, into $var. | |
## NOTE: This represents the actions to be performed and waited upon. | |
for i in {1..1000000}; do | |
var="$i" | |
done | |
# Once the for loop has finished, kill the process executing the 'waiting' method. | |
kill -9 $_PID &>/dev/null | |
# Output the new value of $var. | |
printf "%sOutput of 'var': %s\n" "$clrln" "${green}${var}" | |
echo -e "==>$nc Done with 'method_two'\n" | |
} | |
#### End of [[ method_two ]] | |
######################################################################################## | |
#### [ Main ] | |
#### Below puts both methods/examples to use. | |
echo -e "$blue==>$nc Executing 'method_one'" | |
method_one | |
echo "" | |
echo -e "$blue==>$nc Executing 'method_two'" | |
method_two | |
#### End of [ Main ] | |
######################################################################################## | |
Author
StrangeRanger
commented
Jun 7, 2021
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment