Use read with a timeout -t and set a variable based on its output.
#!/bin/bash
running=true
for ((i=1; i <= 100; i++ )); do
if [[ "$running" == "true" ]]; then
printf "\r%s - %s" "$i" $(( 100 - i ))
fi
if read -sn 1 -t 0.25; then
if [[ "$running" == "true" ]]; then
running=false
else
running=true
fi
fi
done
With this, you can press any key to pause or unpause the script.
running stores true or false to tell if we want the loop to do work or now. read -sn 1 -t 0.25 is the key, it reads one character -n1, it suppresses keypresses -s and waits for only 0.25s -t 0.25. If read times out it returns a none 0 exit status which we detect with the if and only if a key was pressed do we toggle the status of running.
You can also assign the read char to a variable and check for a specific character to limit it to only one key.
if read -sn 1 -t 0.25 key && [[ "$key" = "s" ]] ; then
Use "$key" == "" if you want to check for space or enter.
Note that one side effect of the read + timeout is that if you hit a key the next loop will execute quicker then normal which is made more obvious if you hold down a key.
An alternative might be to use job flow control. ctrl + s will suspend a terminal and ctrl + q will resume it. This blocks the entire shell and does not work in all shells. You can use ctrl + z to suspend a process giving you a prompt back and use fg to resume the process again which allows you to continue to use the shell.