2

Normally, if I run emacs & and then close the shell, emacs will exit.

However, if I run bash -x foo.foo (where foo.foo is a script that runs emacs &), then emacs will remain open even when I exit the shell.

Is there a way to make all processes close when the shell exits, even when the processes were started via a call to bash -x?

3

No, this is not possible:

Normally, when you start a program in the background using & the shell relinquishes control over it, and it will not be terminated when the shell exits. This is true even if you do not use the -x option to bash.

Interactive shells are the exception to this rule: they can do something called “job control” to monitor the child processes they started, and terminate them when the interactive / login shell exits. (This is also configurable; it is possible to leave the background processes running, and that is actually the default behaviour for most processes.)

You can work around this by several means, but only to terminate emacs when the foo.foo script exits, not when the shell calling it exits – this is because calling bash -x runs another (sub)shell, and the interactive parent shell does not “know” about the subshell's children.

0

You could add a trap on EXIT that kills all the processes in your session:

(to add to your .bashrc):

killall_on_exit() {
  sid=$(ps -o sid= -p "$$")
  if [ "$sid" -eq "$$" ]; then
    # we're the session leader
    (
      trap '' TERM
      ps -eo pgid= -o sid= |
        awk -v sid="$sid" '$2 == sid && !seen[$1]++ {print "-" $1}' |
        xargs kill -s TERM --
    )
  fi
}
trap killall_on_exit EXIT

That kills all the process groups in your session. That will not kill the processes that are started in a new session, but since new sessions are typically started by terminal emulators, if you kill the terminal emulator, chances are the process it spawned will die as well (and its children if the leader is an interactive bash with that same trap).

nohup or disown will typically not make commands immune to that.

You could replace the TERMs above with HUPs, but then note that some commands like xterm ignore the SIGHUPs.

To immunize a command against SIGTERM, start it as:

(trap '' TERM; emacs &)

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.