Terminate BASH For loop, that contains long sleep and other stuff, using any specific key
I've not had contact with this kind of tasks for a while, but I remember something like this used to work:
#!/bin/bash
trap break INT
for (( c=0; c<=$1; c++ ))
do
# SOME STUFF HERE
# data gathering into arrays and other commands here etc
echo loop "$c" before sleep
# sleep potentially for a long time
sleep "$2"
echo loop "$c" after sleep
done
#WRITE REPORT OUT TO SCREEN AND FILE HERE
echo outside
The idea is to use Ctrl-C to break the loop. This signal (SIGINT) is caught by the trap, which breaks the loop and lets the rest of the script follow.
Example:
$ ./s 3 1
loop 0 before sleep
loop 0 after sleep
loop 1 before sleep
^Coutside
Let me know if you have any problems with this.
The easiest way is to use Ctrl+C, since by default it gives the INT
signal, which causes most applications to stop, and you can catch it in the shell.
To interrupt the whole loop at once, you could run it in a subshell, and exit
when interrupted. Here, the trap is set only in the subshell, and only it exits.
#!/bin/bash
(
trap "echo interrupted.; exit 0" INT
while true; do
echo "running some task..."
some heavy task
echo "running sleep..."
sleep 5;
echo "iteration end."
done
)
echo "script end."
In some cases it is better to have a solution that does not interrupt "SOME STUFF HERE", and only breaks while the shellscript is waiting.
Then you can use the shell built-in command read
with some options instead of sleep
.
Try this shellscript,
#!/bin/bash
echo "Press 'q' to quit the loop and write the report"
echo "Press 'Enter' to hurry up (skip waiting this time)"
for (( c=0; c<=$1; c++ ))
do
echo "SOME STUFF HERE (pretending to work for 5 seconds) ..."
sleep 5
echo "Done some stuff"
# data gathering into arrays and other commands here etc
# sleep potentially for a long time
#sleep $2
read -n1 -st$2 ans
if [ "$ans" == "q" ]
then
break
elif [ "$ans" != "" ]
then
read -n1 -st$2 ans
fi
done
echo "WRITE REPORT OUT TO SCREEN AND FILE HERE"
You find details about read
with the command help read
,
-n nchars return after reading NCHARS characters rather than waiting
for a newline, but honor a delimiter if fewer than
NCHARS characters are read before the delimiter
-s do not echo input coming from a terminal
-t timeout time out and return failure if a complete line of
input is not read within TIMEOUT seconds. The value of the
TMOUT variable is the default timeout. TIMEOUT may be a
fractional number. If TIMEOUT is 0, read returns
immediately, without trying to read any data, returning
success only if input is available on the specified
file descriptor. The exit status is greater than 128
if the timeout is exceeded