BASH break readline on SIGINT
Question
I try to catch a SIGINT ctrl+c inside a read loop on a socket but the break I'm asking for only get processed after a new line. So when I ctrl+c my running app, I have to wait for a new line to arrive in the socket before the loop breaks / the app exits
This is the minimal version :
trap "break" SIGINT SIGHUP SIGTERM
exec 3<>/dev/tcp/192.168.1.84/50885
while read line
do
echo -e "$line\n"
done <&3
How can I immediately break the loop and exit the app?
Solution
A break
isn't a real command you can execute where ever you want; it is merely a syntactical construct to mark a point where to leave a surrounding loop. Your break
doesn't have a surrounding loop, so it does not make sense (and is an error: bash: break: only meaningful in a `for', `while', or `until' loop
).
You need to kill the read
command instead:
trap "killRead" SIGINT SIGHUP SIGTERM
killRead() {
kill $(cat /tmp/read.pid)
}
exec 3<>/dev/tcp/192.168.1.84/50885
while read line
do
echo -e "$line\n"
done <&3 & pid=$!
echo $pid > /tmp/read.pid
wait $pid
Of course, this is only a very crude solution, not hiding any error messages issued by terminated subshells etc. But it shows the idea and solves the issue you asked about. For hiding expected error message etc. you might want to ask other questions (or just search for already given answers here ;-)