failing to add an exit to this loop

Found this interesting script that draws snow inside your terminal, however.... I would like to have an option to type 'q' at any time to exit the loop. This is what I have;

 

 LINES=$(tput lines)
COLUMNS=$(tput cols)
 
declare -A snowflakes
declare -A lastflakes
 
clear

function move_flake() {    

i="$1"
 
if [ "${snowflakes[$i]}" = "" ] || [ "${snowflakes[$i]}" = "$LINES" ]; then
snowflakes[$i]=0
else
if [ "${lastflakes[$i]}" != "" ]; then
printf "\033[%s;%sH \033[1;1H " ${lastflakes[$i]} $i
fi
fi
 
printf "\033[%s;%sH*\033[1;1H" ${snowflakes[$i]} $i
 
lastflakes[$i]=${snowflakes[$i]}
snowflakes[$i]=$((${snowflakes[$i]}+1))
}
 
while :
do
    
i=$(($RANDOM % $COLUMNS))
 
move_flake $i

for x in "${!lastflakes[@]}"
do
move_flake "$x"
done
 
sleep 0.1
done

this is that I have tried to add ;

echo "Type 'q' to exit out"
while read -n1 -r -p "want to exit the script?"
do
    if [[ $REPLY == q ]];
    then
        break;
    else
        #whatever
    fi
done

added it inside the function, but only ask for the 'q' at the very beginning. then attempted to add the actual script inside the quit loop and only draws an snow flake then ask again if I want to exit.... Any idea how to make this work?


Solution 1:

You can do it like this in the shell bash: Replace the sleep command with a read command, that has a timeout, and let while check for your 'q'. See

help read | less

Here is my version of your snow-show,

#!/bin/bash

LINES=$(tput lines)
COLUMNS=$(tput cols)

declare -A snowflakes
declare -A lastflakes
 
clear

function move_flake() {    

i="$1"
 
if [ "${snowflakes[$i]}" = "" ] || [ "${snowflakes[$i]}" = "$LINES" ]; then
snowflakes[$i]=0
else
if [ "${lastflakes[$i]}" != "" ]; then
printf "\033[%s;%sH \033[1;1H " ${lastflakes[$i]} $i
fi
fi
 
printf "\033[%s;%sH*\033[1;1H" ${snowflakes[$i]} $i
 
lastflakes[$i]=${snowflakes[$i]}
snowflakes[$i]=$((${snowflakes[$i]}+1))
}
 
while [ "$ans" != "q" ]
do
    
 i=$(($RANDOM % $COLUMNS))
 
 move_flake $i

 for x in "${!lastflakes[@]}"
 do
  move_flake "$x"
 done
 read -sn 1 -t 0.1 ans
done