To prevent commands prefixed with a space from appearing in zsh history on macOS, you must configure the
HIST_IGNORE_SPACE option. This setting tells the shell to ignore any command that begins with a whitespace character, effectively keeping sensitive or temporary commands out of your history file while maintaining standard history functionality for other inputs.
Understanding History Behavior in Zsh
By default, most Unix-like shells, including zsh and bash, record every command you type into their respective history files. On macOS, zsh is the default interactive shell since version 10.15 Catalina. While this provides a convenient way to recall previous commands using
Ctrl+R or the up arrow key, it can pose security risks if you are entering passwords, API keys, or private data. It also clutters your history with experimental commands that you do not wish to reuse.
The traditional method to exclude specific commands has been to prefix them with a space. However, this behavior is not enabled by default in zsh. Without proper configuration, even commands starting with a space will be saved to the
.zsh_history file located in your home directory. This article explains how to enable the feature that respects this convention.
Configuring HIST_IGNORE_SPACE
The core solution involves setting the
HIST_IGNORE_SPACE option in your zsh configuration file. This option is part of the broader set of history management options available in zsh. When enabled, any line that starts with a space character is immediately discarded before being added to the history list.
To apply this change permanently, you need to edit your
.zshrc file. This file is sourced every time a new interactive shell session starts. If the file does not exist, you can create it in your home directory. Open your preferred text editor, such as
nano or
vim, and add the following line:
setopt HIST_IGNORE_SPACE
After saving the file, you must reload your configuration for the changes to take effect in the current terminal window. You can do this by running the following command:
source ~/.zshrc
Once reloaded, test the configuration by typing a command with a leading space, such as
echo "secret". Then, press the up arrow key or use
history to verify that the command does not appear in the list. Standard commands without leading spaces should continue to work as expected.
Alternative History Options
While
HIST_IGNORE_SPACE is the most direct solution, zsh offers several other history-related options that might complement your workflow. Understanding these can help you fine-tune how your history behaves.
- HIST_IGNORE_ALL_DUPS: This option prevents duplicate commands from being stored in history. If you run the same command multiple times, only the first instance is kept. This reduces noise in your history list.
- HIST_EXPIRE_DUPS_FIRST: Similar to ignoring all duplicates, this option removes the oldest duplicate entry when a new one is added. This helps manage the size of the history file over time.
- HIST_SAVE_NO_DUPS: This ensures that no duplicate entries are saved at all. It is stricter than
HIST_IGNORE_ALL_DUPS because it actively deletes previous occurrences.
You can combine these options with
HIST_IGNORE_SPACE in your
.zshrc file. For example:
setopt HIST_IGNORE_SPACE HIST_IGNORE_ALL_DUPS
This combination provides a clean history where sensitive commands are ignored, and repetitive commands are consolidated.
Verifying Your Configuration
It is important to verify that your settings are active. You can check which history options are currently enabled by running:
setopt | grep hist
Look for
ignore_space in the output. If it is present, the option is active. If you see errors or unexpected behavior, ensure that there are no typos in your
.zshrc file. Also, remember that changes to
.zshrc only affect new shell sessions. Existing open terminals will not inherit the new settings until they are restarted or the file is sourced.
For more details on how shell source files are processed, you may find it useful to read about
Understanding the Order of Shell Source Files: A Complete Overview. This knowledge helps troubleshoot issues where configurations might be overridden by other scripts.
Security Considerations
Using leading spaces to hide commands is a simple but effective privacy measure. However, it is not foolproof. Some logging tools or system monitors might still capture screen contents or keystrokes regardless of shell history settings. Additionally, if you share your user account with others, they could potentially view your history file directly.
Always treat your shell environment as a semi-private workspace. Avoid storing actual passwords in commands, even if they are hidden from history. Use dedicated secret management tools or environment variables loaded from secure files instead.
Frequently Asked Questions
Does this work in bash as well?
Yes, bash supports a similar feature called
histcontrol. You can add
ignorespace to the
HISTCONTROL variable in your
.bash_profile or
.bashrc to achieve the same result. The syntax differs slightly from zsh's
setopt command.
Can I undo a command hidden by a leading space?
No, once a command is executed with a leading space and
HIST_IGNORE_SPACE is enabled, it is never added to the history list. You cannot retrieve it using
Ctrl+R or the up arrow. You must retype the command manually.
What happens to commands that start with two spaces?
The
HIST_IGNORE_SPACE option ignores any command that starts with at least one space. Therefore, commands with two or more leading spaces are also excluded from history, just like those with a single leading space.
Will this affect my ability to use tab completion?
No, tab completion remains fully functional. The leading space is stripped before the command is executed and before history processing occurs. Completion works based on the characters typed after the space, so your workflow is unaffected.
How do I remove existing history entries now?
To clear your current history file, you can run
history -c in the terminal. To delete the history file entirely, you can remove
~/.zsh_history. Note that this will erase all past commands, including those that were previously visible.