Your last snippet is pretty close to a working solution. What you missed is -t 10 passed to the read command. This introduces an extra delay of 10 seconds in each iteration of the loop. The answer you linked to uses read -t 10 because it addresses a question that uses sleep 10. Until there is a keystroke, read -t 10 does the job of sleep 10.
You wanted to use sleep 1, so use -t 1 in the read command instead:
#!/bin/bashn=10while [ "$n" -gt 0 ]; do n=$((n-1)) # sleep 1 # now we don't need this read -n 1 -t 1 && break # because we have this printf '%3s'" $n"done; read -t 0.1 -n 1000000echoNotes:
- You had
printfaftersleep 1, so here we have it afterread -t 1. - This placement of
printfintroduces a minor problem: if we kept&& n=0you used, then you would see0printed after a keystroke.breakinstead ofn=0solves this. - It makes sense to print a newline character just before exiting. This is what the final
echodoes.
The above is an idle loop. It will work as-is or with an instant command you want to run in every iteration (like df -h in the answer you linked to), but if you want to interrupt an arbitrary command or a script (that may e.g. start long-running commands, possibly asynchronously) when "either n seconds have passed or any key has been pressed", then it won't be that simple. This may be your starting point:
#!/bin/bash</dev/null xeyes &pid="$!"trap 'kill "$pid"' EXITn=10while [ "$n" -gt 0 ]; do n=$((n-1)) read -n 1 -t 1 && break printf '%3s'" $n"done; read -t 0.1 -n 1000000echoYou can run what you want instead of xeyes, but note the kill command inside the trap targets this single process only. If the process ignores signals, creates children or daemonizes itself then this simple kill might not be enough. There are few other strategies, some depend on what the program/script does. I won't elaborate. If you (or anyone) need help with this then ask a new question maybe (after doing research; there are sources that may already be enough). In the new question give an example of a program/script you want to run this way (see mcve).