42

A seemingly new feature in OS X El Capitan (10.11 Beta) is Bash sessions (Terminal sessions). I now have a ~/.bash_sessions directory with history files, and my HISTFILE and HISTIGNORE envars are being overridden. How can I disable all of this functionality?

Whymarrh
  • 13,139
  • 14
  • 57
  • 108
  • 1
    “…my … HISTIGNORE envars are being overridden.” Are you certain? `/etc/bashrc_Apple_Terminal` does not alter `HISTIGNORE` (it isn't referenced at all). – Chris Page Jan 15 '16 at 03:18
  • 2
    *if the`histappend` shell option is enabled, per-session history is disabled by default* – yckart Nov 23 '16 at 01:30

4 Answers4

43

If you startup a new Bash session manually (i.e. bash -xl), you can see what is run on login.

You'll see the following line in the output:

....
+++ '[' '!' -e /Users/username/.bash_sessions_disable ']'

You can create a .bash_sessions_disable file in your home directory to disable this functionality.

Whymarrh
  • 13,139
  • 14
  • 57
  • 108
  • I like having access to a little more history than before, but does it impose any limits on itself? Looks like I have two or three files for every Terminal invocation since installing 10.11. Only two megabytes per month, but still.... – WGroleau Nov 29 '15 at 05:44
  • @WGroleau: This feature isn't about the amount of history, it's about storing separate command histories for each terminal session so that if you restore terminals with Resume the histories will remain separate—like they were when you initially created them. The usual `HISTSIZE` and `HISTFILESIZE` shell variables still apply. In fact, it is recommended that you make one or both of them larger, because each session also appends its history to the global `~/.bash_history` file so all of your history is available in new terminals. See the comments in `/etc/bashrc_Apple_Terminal` for more detail. – Chris Page Jan 15 '16 at 03:21
  • @WGroleau: It also automatically deletes session files older than two weeks, once a day. – Chris Page Jan 15 '16 at 03:22
  • Notice I said two megabytes per MONTH? They are not being deleted. If there were a variable to control that, I would set it to 24 hours. I have never had to recover a session after exiting, and If I ever do, it won't be after I've opened and exited other sessions. it's slightly inaccurate that "all of your history" is available. Each session reads the history. Open another, it reads the same history, without anything from the first session. Each On exit writes the history it knows, overwriting the file. history of the last session is preserved in the .bash_history. – WGroleau Jan 17 '16 at 03:46
  • @WGroleau “They are not being deleted.” Files that are older than two weeks will be deleted once a day—the behaviors are all right there for viewing in `/etc/bashrc_Apple_Terminal`. If you're seeing files older than two weeks, please [file a bug report](https://developer.apple.com/bug-reporting/). If you would like to control how long they remain, also file a report. But if you don't want per-terminal-session command histories at all, you can turn it off with `SHELL_SESSION_HISTORY=0`, as I described in [my answer](http://stackoverflow.com/a/34803825/754997). – Chris Page Jan 18 '16 at 09:15
  • Yes, I read that after my comment. Glad to know it. The other part of comment isn't very clear, so: if you have more than one session open at a time, only the one closed last gets its history saved in ~/.bash_history – WGroleau Jan 18 '16 at 12:54
  • I shall definitely file that bug report. I have never done anything to change the bash session behavior. When I discovered that, I purged all before early November. They currently go back to 8 Nov 2015 and each session has three files: 16K history, ~50 bytes session, and zero bytes historynew (?!?). – WGroleau Jan 21 '16 at 01:45
  • I don't particularly think it is well documented in the /etc/bashrc_Apple_Terminal file. I keep history across terminal windows. I don't want it to be different on mac from linux and I use the same .bashrc and .bash_profile between mac and linux. I don't really understand what it does. What session does it choose to restore? What things does it restore by default? Does it restore env variables? I start a new shell for a reason, with specifically set environment variables, and I don't want to retain temporary changes. /etc/bashrc_Apple_Terminal file seem confusing and undesirable to me. – nroose Mar 14 '16 at 23:45
37

This behavior is defined in /etc/bashrc_Apple_Terminal. It contains documentation comments describing what it does and how to customize it.

You can disable the per-terminal-session command history feature by setting SHELL_SESSION_HISTORY=0 in your ~/.bashrc script, as described here:

You may disable this behavior and share a single history by setting SHELL_SESSION_HISTORY to 0. There are some common user customizations that arrange to share new commands among running shells by manipulating the history at each prompt, and they typically include 'shopt -s histappend'; therefore, if the histappend shell option is enabled, per-session history is disabled by default. You may explicitly enable it by setting SHELL_SESSION_HISTORY to 1.

Note that, although you can disable the entire session-state restoration mechanism by creating ~/.bash_sessions_disable, this is unnecessary just to disable the per-session command history feature, and is not recommended.

Chris Page
  • 18,263
  • 4
  • 39
  • 47
  • 1
    Nice find! Looking through `/etc/bashrc_Apple_Terminal` though leads me to believe that the only way to prevent the feature altogether is to set `"$HOME/.bash_sessions_disable"` (that is, without that file it will still create the sessions directory). – Whymarrh Jan 15 '16 at 17:51
  • @Whymarrh Did you miss part of my answer? I said that that file disables the session-state mechanism—but that's overkill if all you want to do is disable the per-session shell command history. – Chris Page Jan 18 '16 at 01:53
  • 1
    It should be noted that if anyone uses a different terminal, like Alacritty or iTerm, and *never* opens up Apple's Terminal app, none of this additional behaviour will occur. In other words, tonnes of environment variables (`$TERM_SESSION_ID`, `$SHELL_SESSION_*`) and the `~/.bash_sessions` directory will not be created. It's only in opening Apple's Terminal app that all of these extras are created. – danemacmillan Jan 24 '19 at 00:40
11

To summarize, this has to do with Apple's Resume feature. When this feature is enabled, when you quit an app or reboot, the next time the app opens it will open the windows that were previously open.

With regard to Terminal, three things have to be in place for this to happen:

  1. $HOME/.bash_sessions_disable must not be present
  2. System Preferences/General/Close Windows when quitting an app must not be checked.
  3. When rebooting, select Reopen windows.

When you reopen Terminal, it will reopen the same windows and tabs you had before in the same screen positions. Additionally, if you have checked Terminal/Preferences/your-window-type/Windows/Resume/Restore-text-when-reopening-windows, it will restore the text on each screen.

Finally, and this relates specifically to the OP's question, it will restore the history in each window/tab if the following conditions hold:

  1. SHELL_SESSION_HISTORY is unset or set to 1
  2. shopt histappend is not set
  3. HISTTIMEFORMAT is not set

If SHELL_SESSION_HISTORY is explicitly set to 1 in .bashrc, the last two requirements are overridden, that is, shopt histappend or HISTTIMEFORMAT could be set.

Additionally, attention needs to be paid to the HISTSIZE and HISTFILESIZE variables. They should not be too large or too small, and some advise to leave them unset so they take Apple's default values.

chetstone
  • 650
  • 1
  • 9
  • 19
  • `echo $HISTSIZE` and `echo $HISTFILESIZE` will show your current settings. Mine are `500`. Are those the default values? How to "unset" them would be helpful info. – John Sep 19 '20 at 19:57
2

Everything so far written about this subject is accurate and useful, and the techniques already mentioned should be used in lieu of this. I'm going to mention a totally nuclear approach, just for the sake of entertaining alternatives, and also to expand further understanding of this subject.

The only reason I acquired this knowledge is simply because I was looking for an alternative solution to needing to create a ~/.bash_sessions_disable file; I would have instead preferred preventing the sessions behaviour from happening by just adding some lines to my existing ~/.bash_profile. Unfortunately, that is not possible without going nuclear, so the official answer is still the best approach.

Summary

When Bash first starts up on MacOS, it will first source /etc/profile, which in turn sources /etc/bashrc. The contents of that file include this line:

[ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"

The $TERM_PROGRAM environment variable is only set by Apple's Terminal app. Printing the value of that variable returns Apple_Terminal. In other words, the /etc/bashrc file is attempting to source a /etc/bashrc_Apple_Terminal file if it both exists and is readable. It's in this file where MacOS does its special Bash session handling to tie into the Resume features of the OS.

After all that, Bash will then source any configurations a user has in their home directory (like ~/.bash_profile or ~/.bashrc). This being stated, there's no way to override all the work done in the /etc/bashrc_Apple_Terminal file on a purely configuration level (vs both configuration and creating a new file) without doing what the others have mentioned, namely, setting $SHELL_SESSION_HISTORY to 0 to eliminate session-based history, and creating a ~/.bash_sessions_disable to prevent the .bash_sessions directory from being created every time Apple's Terminal is started.

Nuclear Approach

The two possible alternatives to eliminate any of this new MacOS functionality would be to either 1) remove that last line from the /etc/bashrc file, or 2) rename or delete the /etc/bashrc_Apple_Terminal to something else.

After doing this, Apple's Terminal app will no longer behave differently than non-Apple terminal emulators.

danemacmillan
  • 1,202
  • 12
  • 13
  • Yea, as far as a very quick cursory glance shows the only thing that `/etc/bashrc_Apple_Terminal` does is the resume feature. It's complex enough, and terminal sessions to remote systems are complex enough, and Mac's track record is poor enough, that I had little confidence that I was going to like it, and therefore I spent no time in disabling it entirely and getting rid of this extra fluff interrupting my usual *nix workflow: `sudo vim /etc/bashrc` and comment out the last line is a nice quick solution. Sigh. Free again. (I see someone says "not recommended" lol but no reason given) – NeilG May 01 '22 at 04:06