Does bash have a hook to determine when child shell exits?

In bash I spin up a t/csh shell, which updates the tty input (stty erase ^H) in the .cshrc, but when exit-ing and returning to bash the backspace key no longer works. This is because bash uses readline and I need to reset the erase (stty erase ^?).

If I understand trap correctly, it seems like I could trap the t/csh exit from within the t/csh process, and run commands after it exits. However, my preference would be for the trapping to occur in bash, which ideally would detect a shell was called/exited and then run a script to reset its configurations.

This is preferred because I could call any number of shells (e.g., dash, zsh), which may inadvertently modify bash-specific settings. Instead of maintaining multiple trap commands for each shell, it seems like it would be best to have one for bash.


Is my understanding of trap correct? If so, is it possible for bash to detect a child shell exit and then run a script?


Solution 1:

You were on the right track with trap. What you want is the following:

trap "stty erase ^?" SIGCHLD

You can add that to .bashrc. Note that this will run when any subprocess ends.

This will only work in interactive sessions. For non-interactive sessions, bash will not enable job control by default, so you will need to run set -o monitor first. But I doubt you'd need backspaces in non-interactive scripts.

SIGCHLD is sent to the parent process whenever a subprocess exits.


An alternative method is to wrap your other shell in a script, such as:

#!/bin/sh
tcsh
stty erase ^?

Then, if you launch your shell through the script, the script will run the stty erase command after the shell exits. This is less likely to have side effects than a global trap handler, but of course it'll only work if you launch through the script every time (or create an alias to do so, e.g. alias 'tcsh' '~/launch-tcsh.sh').