9

Typical scenario:

I temporarily need to access a file that my vhost prevents me from accessing. I fire up vim, edit the settings and background vim to tell apache to reload its configuration.

Problem:

If I now forget about this, my shell will tell me "There are stopped jobs", when I CTRL+D the session. However, since I have a habit of having shells in shells in shells, due to ssh, tmux and similar, I also frequently repeatedly send EOF when I wrap my work up and close my windows. This in turn causes me to accidentally kill the shell, despite the warning.

Can I make it harder to kill such shells?

user50849
  • 5,202
  • 6
    :! service apache reload instead of backgrounding vim? (Doesn't solve your question, but maybe solves your problem?) – Ulrich Schwarz Jun 13 '12 at 09:54
  • 1
    It's an interesting workaround that I haven't though about, +1. It will often be a valid workaround, but obviously it's unfortunately vim specific. – user50849 Jun 13 '12 at 10:24
  • Just to nitpick, this is not about your terminal but your shell - have a look at http://unix.stackexchange.com/questions/4126/what-is-the-exact-difference-between-a-terminal-a-shell-a-tty-and-a-con – Ulrich Dangel Jun 13 '12 at 16:25
  • I updated the question to reflect this, but after reading the linked to answer, I'm wondering if use of "terminal" should have stayed in some places. Obviously you could update the text yourself to make it better. :) – user50849 Jun 13 '12 at 18:25

2 Answers2

10

If you are using bash, you can set the IGNOREEOF shell variable to a number that specifies how many consecutive EOF chars the shell should ignore before treating the EOF as an exit signal. Check the man page for specifics.

However, that triggers before the "there are stopped jobs" message triggers, so you still have the same problem - you get that message, and one more ^D exits the shell.

An alternative is to put the number of shell jobs into your prompt if that number is greater than zero.

For example, an excerpt from my .bashrc:

PROMPT_COMMAND=prompt_command
prompt_command() {
    job_count=$(jobs | wc -l)
    if [ $job_count -gt 0 ] ; then
        prompt_job="[$job_count] "
    else
        prompt_job=""
    fi
}
PS1="...\${prompt_job}..."

After this the shell may look like ...[1] ...

That puts a job count in your prompt if it is greater than zero. This makes it easy to see when you have incomplete jobs and works well (for me) as a visual reminder that jobs are still running.

user50849
  • 5,202
camh
  • 39,069
  • Great idea, I'll try to incorporate that into my terminal :) You had a tiny error in the script that made it fail, I've submitted an edit request. – user50849 Jun 13 '12 at 10:29
  • Actually, maybe the error didn't matter. – user50849 Jun 13 '12 at 10:34
  • @user50849: The error would have mattered (silly typo). I have applied the edit (obviously, replace the ... with whatever else you want in the prompt). – camh Jun 13 '12 at 10:36
  • 2
    Can get the same result, in bash, by using \j instead of the \${prompt_job} string above. – Arcege Jun 13 '12 at 13:23
  • @Arcege: It's not quite the same. I want nothing in my prompt when there are no jobs, not [0]. That way, it stands out when you have background jobs present. – camh Jun 14 '12 at 01:00
4

Based on the previous answer I came up with this

PROMPT_COMMAND=protect_bg_jobs

protect_bg_jobs()
{
    if [ "$(jobs)" == "" ]; then
        set +o ignoreeof
    else
        set -o ignoreeof
    fi
}

It hides the "There are stop jobs" message but it will save my vim buffers.

Jan J
  • 41