1

When searching for a way to do this on Google, all I can find are ways to quit the session without saving history (like kill -9 $$), but I have the opposite problem. I want to save all of my history, just not the exit command.

Comcast has really abused us at work such that our SSH tunnels can't stay up for more than 5 minutes without getting broken pipe. After reconnecting, I go to run the last command and sure enough, I forget it's now exit!

  • 1
    If you keep losing your connection, GNU screen would be a good idea. It will allow you to get back into your previous session with everything intact. – Barmar Mar 04 '15 at 21:42
  • @drewbenn His problem is that it's not saving everything else in the history file. How will filtering out exit make it save the other stuff? – Barmar Mar 04 '15 at 21:43
  • For your comcast problem, try adding ServerAliveInterval 30to your ~/.ssh/config, they may be killing idle connections. – Stéphane Chazelas Mar 04 '15 at 21:45
  • Right now it's at 60 @StéphaneChazelas, I'll try decreasing it. – NobleUplift Mar 04 '15 at 21:46
  • Really it's just a build server, so before I would just log in, run the build, keep it open all day, and then let the pipe break when my computer goes to sleep. To deal with Comcast, I enclosed my pipe in a script that automatically restarts and logs broken pipes (we were going to present this information to Comcast, until we found out they don't care), so I have to manually exit at the end of the day otherwise it would log the entire night as downtime. – NobleUplift Mar 04 '15 at 21:50
  • 1
    Use ctrl-D instead of exit to terminate your session. – wurtel Mar 05 '15 at 08:19
  • Adding HISTIGNORE=exit does seem to be working for me. But CTRL+D works great! It would be nice to get HISTIGNORE working through. – NobleUplift Mar 05 '15 at 17:24
  • This might sound dumb @wurtel, but want to post that as an answer? I don't know how I didn't know about CTRL+D until now. – NobleUplift Mar 13 '15 at 16:00
  • @NobleUplift done – wurtel Mar 16 '15 at 08:10

2 Answers2

1

If @StéphaneChazelas's suggestion of increasing ServerAliveInterval doesn't work (maybe try a value of 300), then you might want to consider something like GNU screen or tmux so you can resume your dropped connections.

I have this near the top of my ~/.bashrc on all of my remote systems:

screen -r >/dev/null 2>&1

This will do nothing if you lack a disconnected screen session (e.g. if it's your second connection, or if you just rebooted), but if you do have a screen session (that is not attached elsewhere), it will automatically reattach you. Bam, all of your previous history (and active commands, etc.) are restored. (This assumes you launch screen on your first login.)

I also couple this with a looped SSH connection. Here's a simple version to illustrate what I'm talking about:

while sleep 1; do ssh remotehost; done

This way, when you are disconnected, you'll automatically reconnect (this is even transparent, assuming you have an ssh key and are using ssh-agent or a passwordless key).

Adam Katz
  • 3,965
1

The shell will read commands from your terminal (i.e. the shell's standard input) until it's told to stop (by entering the exit command) or when an end-of-file (EOF) is encountered (just like when the shell is executing a script).

If you enter the exit command, this will first be saved into the history, and then the shell will quit. Entering ctrl-D generates an EOF; as this is not a command but an input state, it can't be saved in the shell's history.

Note that you can instruct bash to ignore EOF; this can be done in 2 ways:

  • set -o ignoreeof
  • IGNOREEOF=n

The first way is equivalent to doing IGNOREEOF=10, meaning you have to hit ctrl-D 10 times in a row before the shell will exit. This is to prevent accidentally terminating the shell e.g. if you mistype ctrl-C or whatever.

Note also that ctrl-D only generates an EOF when entered as the first thing on a line (i.e. after an enter), bash ignores it if anything has already been typed on the line.

The ctrl-D also generates EOF outside the shell. E.g.:

$ wc
foo bar
<ctrl-D>
      1       2       8

wc has counted 1 line, 2 words, 8 characters (including the newline).

Here's an example with using ctrl-D after some input has been given on the line:

$ wc
foo bar<ctrl-D><ctrl-D>       0       2       7

Now wc has counted zero lines (no enter had been given), 2 words and 7 characters. Two ctrl-D sequences were necessary because data had already been given; note that bash handles this specially (ignoring the EOF if something has already been entered on the line), whereas e.g. dash doesn't. This is probably due to the line editing facility in bash.

wurtel
  • 16,115