1

I stumbled upon this unexpected behavior and I was hoping someone with a better understanding could explain it!

I have a function that is called by a script and run as a background process - some_function & - When I assigned it to a variable xxx=$(some function &) I noticed that killing the script also killed this process. However, when it is not assigned to a variable killing the script leaves the process running!

Why is this? I figured that assigning the command to a variable kept it attached to the script so that killing the script killed it as well? This is benneficial to me, i just want to understand it. The function itself does not return anything.

Here is the code:

screen_saver_function () { while true; do echo "some phrase"; done }
yyy=$(cat /dev/$tty > /tmp/tty &)
xxx=$(screen_saver_function > /dev/$tty &)
while true; do [[ ! -z $(cat /dev/$tty) ]] && break; done

The idea is I am trying to pass the output of screen_saver_function to a terminal (first line) that will then terminate when a key is pressed. This I am accomplishing by writing any text from the terminal into a file and exiting the script when text appears in that file. Its horribly hackish, I know, but it works. I was capturing $! and pkilling it to exit the background processes when I happened upon the odd behavior described.

7
  • 1
    Please post a complete example. Assigning the output of a function does in no way "attach" it to its parent script. Simple example: bash -c 'foo(){ echo subproc=$BASHPID >&2; sleep 777; }; (sleep 1; kill -TERM $$) & v=$(foo&)'. If you ps <process shown by subproc> you'll see that it's still running even after its parent script was killed.
    – user313992
    Dec 2, 2019 at 5:40
  • 2
    Your function most likely dies because of a SIGPIPE signal, when it tries to write something to its stdout, which has become a pipe with no reader when the parent script has died. Also notice that var=$(cmd &) most of the time doesn't really make sense, because the script will have to wait until cmd has either terminated or closed/redirected its stdout -- so cmd is not really running in "background".
    – user313992
    Dec 2, 2019 at 5:44
  • Updated with the code @mosvy. Thank you for your explanation, I think your second comment probably explains it. If I understand you, the output of the function is being written to both /dev/tty and the variable (either xxx or yyy). When the script ends, xxx/yyy no longer exists and the process fails. Is this correct? Does this mean I am using twice as many resources by writing the output of the function too two destinations? Dec 2, 2019 at 8:33
  • If screensaver function has asychronous command delimiter ( the ampersand ) defined within the function, my guess would be that calling screensaver_function & is doing the same as described in unix.stackexchange.com/a/267241/85039 However, it's just a guess, since we've no idea what screensaver_function actually does, or if it traps signals, etc. As for why it terminates when command-substitution with variable assignment is in place - that's a mystery to me Dec 2, 2019 at 9:11
  • @SergiyKolodyazhnyy edited to add an example of screen_saver_function. Dec 2, 2019 at 18:08

1 Answer 1

1

In xxx=$(some function &), yes you're running some function asynchronously in that subshell, but its stdout is still connected to the writing end of the pipe created by the command substitution.

So, while the subshell will exit straight away after starting some function asynchronously, the parent shell, which is reading the output of the command substitution from the reading end of that pipe to fill the $xxx variable will still wait for end-of-file on that pipe, which will not happen until some function finishes.

If the parent shell is killed, then the reading end of the pipe is closed, and some function will get a SIGPIPE the next time it tries to write to stdout (which goes to the pipe).

1
  • Although the OP didn't ask for it, is there some functional use for x=$(fn &) vs. x=$(fn)? The shell will wait for fn to complete in either case.
    – jrw32982
    Dec 18, 2019 at 22:38

You must log in to answer this question.

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