docs/docs/guide/shell-integration.md
Atuin uses shell hooks to capture your command history. This page explains how the integration works, why Atuin might not record commands in certain environments, and how to control what gets recorded.
When you add eval "$(atuin init <shell>)" to your shell configuration, Atuin installs hooks that run at specific points in your shell's command lifecycle:
These hooks only activate under specific conditions:
-i or inherently interactive).bashrc, .zshrc, etc.)atuin init command must run during shell startupIf any of these conditions aren't met, Atuin's hooks won't be installed, and commands won't be recorded.
When Atuin initializes, it sets several environment variables:
| Variable | Purpose |
|---|---|
ATUIN_SESSION | Unique identifier for this shell session |
ATUIN_SHLVL | Tracks shell nesting level |
ATUIN_HISTORY_ID | Temporary ID for the currently executing command |
ATUIN_HISTORY_AUTHOR | Optional command author identity (for example ellie, claude, copilot) |
ATUIN_HISTORY_INTENT | Optional command intent/rationale text |
These variables are used internally to track command execution and associate commands with sessions.
If ATUIN_HISTORY_AUTHOR is not set, Atuin defaults to the local shell username.
Many development tools include embedded terminals:
These tools often spawn shells differently than your regular terminal, which can prevent Atuin from working.
Embedded terminals commonly:
bash -c "command" or similar, which doesn't trigger shell configuration.bashrc/.zshrc for performance or isolationYou can verify whether Atuin is active by running:
atuin doctor
Look for the shell.preexec field in the output. If it shows none, Atuin's hooks aren't installed in that shell session.
If you want Atuin to record commands from an embedded terminal, you'll need to ensure it starts an interactive shell that sources your configuration.
Most IDEs let you customize the shell command used for their integrated terminal:
PyCharm / IntelliJ:
-i flag:
/bin/bash -i or /bin/zsh -iVS Code:
Add to your settings.json (substitute the shells for whatever you use):
{
"terminal.integrated.profiles.linux": {
"bash": {
"path": "/bin/bash",
"args": ["-i"]
}
},
"terminal.integrated.profiles.osx": {
"zsh": {
"path": "/bin/zsh",
"args": ["-i"]
}
}
}
For tools that don't easily support shell arguments, create a wrapper script:
#!/bin/bash
# Save as ~/bin/interactive-bash.sh and chmod +x
exec /bin/bash -i "$@"
Then configure your IDE to use ~/bin/interactive-bash.sh as the shell path.
After configuring, open a new terminal in your IDE and run:
atuin doctor | grep preexec
You should see built-in, bash-preexec, blesh, or similar—not none.
Sometimes you don't want certain commands in your history. This is common when:
The history_filter option in ~/.config/atuin/config.toml lets you exclude commands matching specific patterns:
history_filter = [
"^ls$", # Exclude bare 'ls' commands
"^cd ", # Exclude cd commands
"^cat ", # Exclude cat commands
]
Patterns are regular expressions. They're unanchored by default, so secret matches anywhere in a command. Use ^ and $ for exact matching.
To exclude all commands run from specific directories:
cwd_filter = [
"^/tmp", # Exclude commands run from /tmp
"/node_modules/", # Exclude commands from any node_modules
"^/home/user/scratch", # Exclude a scratch directory
]
Most shells support "ignorespace"—commands prefixed with a space aren't saved to history. Atuin honors this convention:
echo "this won't be saved" # Note the leading space
!!! warning "Bash with bash-preexec" When using bash-preexec (not ble.sh), there's a known issue where ignorespace isn't fully honored. The command won't appear in Atuin, but may still appear in your bash history. See installation for details.
If a tool spawns interactive shells but you don't want its commands recorded, you have several options:
Modify your shell configuration to skip Atuin initialization based on an environment variable:
# In .bashrc or .zshrc
if [[ -z "${MY_TOOL_SESSION}" ]]; then
eval "$(atuin init bash)"
fi
Then configure your tool to set MY_TOOL_SESSION=1 when spawning shells.
If the tool runs predictable commands, filter them:
history_filter = [
"^git status$",
"^git diff",
"^ls -la$",
]
If the tool operates in specific directories:
cwd_filter = [
"^/path/to/tool/workspace",
]
After adding filters, you can remove matching entries from your existing history:
atuin history prune
This removes entries that match your current history_filter or cwd_filter patterns.
Atuin supports two preexec backends for Bash:
The shell integration explicitly checks for interactive mode:
if [[ $- != *i* ]]; then
# Not interactive, skip initialization
return
fi
Zsh has native hook support via add-zsh-hook. The integration is straightforward and works reliably in interactive sessions.
Fish uses its event system (fish_preexec and fish_postexec events). It also respects Fish's private mode—commands run with fish --private aren't recorded.
atuin doctor and check the outputshell.preexec is not noneecho $- should contain i)atuin init is in your shell config and being sourcedbash -i or zsh -ihistory_filter in your configcwd_filter for directory-based exclusionatuin history prune to clean existing entriesThis is the most common issue. The IDE's embedded terminal likely isn't starting an interactive shell. See Enabling Atuin in Embedded Terminals above.