I am working with a large Bash code base where most scripts disable job control and the DEBUG trap is used extensively. I noticed that if I tried to run my scripts in the background, the interactive shell that started them would immediately exit on any keyboard input. A simple repro is to run
bash +m -c "/bin/echo ; trap 'trap DEBUG' DEBUG ; sleep 10" & in an interactive shell with job control enabled. Hit Enter a few times. The shell that launched this background process exits. The background process itself appears to be killed by a signal. I was able to repro this with and under Bash-5.2.21 and 5.1.16 on Ubuntu 22.04.4, and with Bash-5.2.15 on MacOS. The problem seems to be triggered by the following code in run_debug_trap(): if (pipeline_pgrp > 0 && ((subshell_environment & (SUBSHELL_ASYNC|SUBSHELL_PIPE)) == 0)) give_terminal_to (pipeline_pgrp, 1); give_terminal_to() calls tcsetpgrp (shell_tty, pgrp), which places the calling process in the foreground without the parent shell's knowledge. Since the parent shell's process group is no longer in the foreground, I suspect it receives an EIO from a read(2) and exits, although I was not able to confirm this with strace. In my repro pipeline_pgrp is non-zero at the time of DEBUG trap execution. gdb shows that it was set to shell_pgrp in make_child() that forked /bin/echo without job control (+m). The other condition of the if statement is also satisfied. -Mark