2

In bash, I'm observing that calling kill on a sleeping process won't kill it if I start out with a subshell. Can you help me understand why?

function foo () {
  # Start a loop with `sleep` in the background
  while true; do
    >&2 echo looping
    sleep 5
  done &
  # Wait for user input, then kill the "sleep" loop
  loop_id=$!
  read -p 'press enter' DUMMY
  kill $loop_id
}

echo $(foo) # Call foo within a subshell
echo "DONE"

Two very different things can happen, depending on whether that last line uses a subshell

  • With the subshell invocation echo $(foo), if I press enter to satisfy the read call, then the script doesn't terminate until after the sleep concludes.
  • If I invoke the function with just foo instead of $(foo), then the script terminates as soon as I press enter.

I've really on this toy example, but in my real work, I want to capture stdout from foo into a shell variable, so I want to kill the subshell asap. Is there a way for me to achieve both parts of my goal?

1 Answer 1

3

When you use the command substitution $(foo), the shell needs to wait until all input from the command substitution has been received. The sleep you're running has a copy of the file descriptor (probably a pipe) that's connected to where the shell reads the output of the command substitution. (I'm also pretty sure the $! will give the PID of the shell running the while loop, and not the sleep inside it.)

Consider e.g. this script:

foo() {
    sleep 5 &
    echo foo
}
tmp=$(foo)
echo end.

Running it takes 5 seconds.

But change the sleep line to sleep 5 > /dev/null &, and now the script returns immediately, because the sleep is no longer connected to the command substitution. Note that the backgrounded sleep will still be running there, in the background, until it times out. You're just not likely to notice it.

Note that that's specific to the command substitution, not just any subshell environment. ((foo) would also be a subshell, but should work similarly to { foo; }, or just foo here.)

1
  • Wow! Thanks for the thorough explanation and solution!
    – Jellicle
    Commented Sep 21, 2021 at 23:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .