This is more of a process management/signal handling question than a Bash question. It just uses Bash to explain the issue.

I'm running a Bash script in which I run a background process. This is the script:


# ...

# The background process
  while :; do
    sleep 1 && echo foo >> /path/to/some/file.txt
} &

# ...

exit 0

I do NOT run the script itself in the background. Simply ./script.

The "huponexit" shell option is enabled using shopt -s huponexit, therefore when the terminal is being closed I expect it to send a HUP signal to Bash, which will propagate it until it reaches the background process. If the background process will not trap and ignore the signal, it will be killed too - but this is not happening. The background process acts as if it was disown'ed.

This is a scheme I draw to illustrate the issue. The scheme, along with the description above, can be wrong as I'm sure I do not understand the subject well enough. Please fix me on that if it is truly the case.

enter image description here

I want to know why the background process is not being killed after closing the terminal, as if it was invoked by an interactive shell like that:

rany@~/Desktop$ while :; do sleep 1 && echo foo >> /path/to/some/file.txt; done &

I'm not sure but I guess that the answer to my question lies in the fact that Bash fork()s a non-interactive shell to run the script which might have a different set of rules for job control and signal handling.


So what does the man page tell us about huponexit?

If the huponexit shell option has been set with shopt, bash sends a SIGHUP to all jobs when an interactive login shell exits.

EDIT: Emphasizing that it is a LOGIN shell.

EDIT 2: interactive deserves equal emphasis

  • I'm also specifing that in my question: "The "huponexit" shell option is enabled using shopt -s huponexit, therefore when the terminal is being closed I expect it to send a HUP signal to Bash". Actually, this is what I want it to do. I set it on purpose. – Rany Albeg Wein Apr 21 '13 at 23:24
  • @RanyAlbegWein Your case does not refer to an interactive login shell thus you can set huponexit a hundred times, it won't make a difference. Check the output of echo $- (and compare to that in your shell) if you don't believe that. The { } creates a new bash process. Your HUP kills the parent bash (the one running the script) which (as non-interactive) does not kill its children (the {} bash). – Hauke Laging Apr 21 '13 at 23:37
  • Didn't notice that it says "interactive login shell". So if I run this script from a login shell with a "huponexit" set, then the scenario that I described above will happen? i.e. The background process will also be killed. Thank you. – Rany Albeg Wein Apr 21 '13 at 23:53
  • @RanyAlbegWein No, you missed two points, me one. This is about the status of the script (the shell running the script) not (at least not so much) about the status of the shell which called the script. The script itself must be both interactive and an login shell. You either have to start the script as bash -i -l ./script or you have to adapt the shebang line in the script to #!/bin/bash -i -l. It seems not to be possible to reconfigure a running shell to interactive and login status. – Hauke Laging Apr 22 '13 at 0:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.