I've found that a signal from kill is not delivered from a subshell until the subshell completes: eg. FUNCTION() { kill $1 sleep 1 ps | grep $1 } When called as follows, as expected the backgrounded process is killed by FUNCTION(): # while true; do sleep 1; done & # echo $! 26276 # FUNCTION 26276 26624 root 4164 S grep 26276 [1]+ Terminated while true; do sleep 1; done # But when called in a subshell, the background process doesn't appear to be killed until the subshell returns: # while true; do sleep 1; done & # echo $! 29632 # ret=$(FUNCTION 29632) [1]+ Terminated while true; do sleep 1; done # echo "$ret" 29632 root 0 Z [sh] 31456 root 4164 S grep 29632 Is that expected behaviour?