Search code examples
bashshellterminalshkill-process

Is it possible to execute a bashscript after kill a terminal?


I know that have a file called .bash_profile that executes code (bashscript) when you open a terminal.

And there is another file that is called .bash_logout that executes code when you exit the terminal.

How I would execute some script when terminal is killed?

(.bash_logout do not cover this when terminal is killed).


Solution

  • How I would execute some script when terminal is killed?

    I interpret this as "execute a script when the terminal window is closed". To do so, add the following inside your .bashrc or .bash_profile:

    trap '[ -t 0 ] || command to execute' EXIT
    

    Of course you can replace command to execute with source ~/.bash_exit and put all the commands inside the file .bash_exit in your home directory.

    The special EXIT trap is executed whenever the shell exits (e.g. by closing the terminal, but also by pressing CtrlD on the prompt, or executing exit, or ...).

    [ -t 0 ] checks whether stdin is connected to a terminal. Due to || the next command is executed only if that test fails, which it does when closing the terminal, but doesn't for other common ways to exit bash (e.g. pressing CtrlD on the prompt or executing exit).

    Failed attempts (read only if you try to find and alternative)

    In the terminals I have heard of, bash always receives a SIGHUP signal when the window is closed. Sometimes there are even two SIGHUPs; one from the terminal, and one from the kernel when the pty (pseudoterminal) is closed. However, sometimes both SIGHUPs are lost in interactive sessions, because bash's readline temporarily uses its own traps. Strangely enough, the SIGHUPs always seem to get caught when there is an EXIT trap; even if that EXIT trap does nothing.

    However, I strongly advise against setting any trap on SIGHUP. Bash processes non-EXIT traps only after the current command finished. If you ran sh -c 'while true; do true; done' and closed the terminal, bash would continue to run in the background as if you had used disown or nohup.