MacOS Catalina terminal tab doesn't remember its own previous commands
I upgraded from El Capitan to Catalina recently; when I click ↑ in any terminal tab it used to toggle previous commands executed within that specific tab only, but now it will show commands for all tabs which is very annoying
Is there any setting to fix that?
Solution 1:
Your question regards how the shell maintains its command history. In switching from El Capitan, to Catalina, you may have also switched your default shell from bash
to zsh
, and these shells have different defaults for maintaining their command history. This answer assumes your question is for altering the behavior of the zsh
command history.
You have at least two choices:
-
Restore
bash
as your shell:% chsh -s /bin/bash
This is easily changed if you decide to return to
zsh
:chsh -s /bin/zsh
-
Configure
zsh
to disable the "aggregation" of command histories seeAPPEND_HISTORY
From
man zshoptions
:APPEND_HISTORY
If this is set, zsh sessions will append their history list to the history file, rather than replace it. Thus, multiple parallel zsh sessions will all have the new entries from their history lists added to the history file, in the order that they exit. The file will still be periodically re-written to trim it when the number of lines grows 20% beyond the value specified by $SAVEHIST (see also the HIST_SAVE_BY_COPY option).Accordingly, if you wish to continue using
zsh
as your shell, you can un-set theAPPEND_HISTORY
option, and the command histories from your various terminals/shells will not be aggregated into a single history.You can check to see which options are set or unset as follows:
% setopt ... # lists options that are set % unsetopt ... # lists options that are unset % set -o ... # lists all options w/ off/on status
NOTE:
setopt
only prints the options not enabled by default. The APPEND_HISTORY option is set by default - as designated by the<D>
seen in the man page excerpt above.Now, this is a bit obtuse (IMO at least), but notice that there is an option appearing in the
unsetopt
output namednoappendhistory
. This is explained in the zsh Options documentation as follows:In the following list, options set by default in all emulations are marked ; those set by default only in csh, ksh, sh, or zsh emulations are marked , , , as appropriate. When listing options (by ‘setopt’, ‘unsetopt’, ‘set -o’ or ‘set +o’), those turned on by default appear in the list prefixed with ‘no’. Hence (unless KSH_OPTION_PRINT is set), ‘setopt’ shows all options whose settings are changed from the default.
(emphasis mine)
It comes down to this: the option to give you the behavior you want is set as follows:
setopt noappendhistory
Add this command to your
~/.zshrc
file using your favorite editor. Once you've done that,source
this file as follows:% . ~/.zshrc -- OR -- % source ~/.zshrc
Solution 2:
This answer assumes the question concerns the behavior of the command history function in zsh
.
I feel two points should be made before proposing an answer:
- Information available online for
zsh
often refers to a "default configuration". As far as macOS is concerned, thezsh
"default configuration" may differ from that described in other sources. The "macOS default configuration" is thezsh
"default configuration" as modified by/etc/zshrc
. It's best to review this file before making changes, AND all changes should be made in the local user's~/.zshrc
file. - It helps (me at least) to understand that the shell can maintain two (2) command histories. One is a history file (by default:
~/.zsh_history
), the other one is a session history that is cached or retained in memory for each session. The parametersSAVEHIST
andHISTSIZE
determine the depth of the history file, and the session history, respectively. This can be confusing, and the figure below, while not technically accurate, may help in understanding the concept.
For each session, there is a unique session history. However, there is (by default) only one file history for all sessions. Under the macOS default configuration (ref. /etc/zshrc
): HISTSIZE=2000
, SAVEHIST=1000
. When a new session is started, the session history is empty. However, assuming the file history is not empty, pressing the up arrow key (⬆︎) will reveal commands issued from other sessions. As time goes on - as commands are issued in this new session - its session history will begin filling commands entered in this new session. After, say, 20 commands have been issued, the up arrow (⬆︎) will reveal those 20 commands; the next up arrow key press will reveal the latest entry in the file history.
In summary: In a new session under the macOS default configuration (HISTSIZE=2000
, SAVEHIST=1000
) your command history is drawn from the history file, which is to say from the session histories of other sessions. As more commands are issued in this new session, these session commands will "push" commands from the history file further down in the stack.
As I understand your question, you do not wish your session histories to co-mingle. That is, for any session, you do not want to see any command history from another session - from the history file. After reading the above, if this is the behavior you want, here is one way to do that:
Proposed Answer: Set SAVEHIST=0
and HISTSIZE=2000
Open the file ~/.zshrc
in your editor, and add the following two lines which override the macOS defaults:
SAVEHIST=0
HISTSIZE=2000
SAVEHIST=0
will prevent any session from saving its history to the history file. Each session will have a command history consisting only of its unique session history. The up and down arrow keys (⬆︎, ⬇︎) will never show a command from another session because as far as the current session is concerned, that history does not exist. Potentially undesirable side effects of this option are:
-
new sessions have no command history
-
if a session is closed or terminates, command history is lost, but see Note 4 below.
If you tend to keep sessions open for long periods of time (as I do), you could set HISTSIZE
to a larger value to postpone "pruning" when the history reaches 120% of its allocation (2,400 commands in this case).
If you wish to retain the history file,zsh
provides a large number of options for controlling how the history file and session history are maintained, and how they interact with each other to present your command history. In addition the fc
commands are shell built-ins that allow manipulation of the the command history (see also: 1, 2, 3). Beyond the options native to zsh
are numerous 3rd party tools dedicated to the command history function - even a tool that stores command history and related tidbits in a relational database. I would summarize by saying, "The shell command history suffers from an embarrassment of riches."
Notes:
-
Note that the name
~/.zsh_history
is not a standard forzsh
- it is simply the filename that Apple has chosen. -
Apple defines their defaults for
zsh
in the file/etc/zshrc
. It's instructive to review these, but it's probably best to make changes to the defaults within your local configuration file at~/.zshrc
. -
HISTFILE, HISTSIZE and SAVEHIST are covered in the
zshparam
manualsHISTFILE (from
man 1 zshparam
) The file to save the history in when an interactive shell exits. If unset, the history is not saved.HISTSIZE (from
man zshparam
) The maximum number of events stored in the internal history list.SAVEHIST (from
man zshparam
) The maximum number of history events to save in the history file. -
The
fc
commands are shell built-ins that allow manipulation of the the command history (see also: 1, 2, 3).