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?

Was it helpful?

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 ;-)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top