起因
我有 3 台机器(笔记本 + 两台服务器),每台 bash 历史互相不通。
"那条神秘的 ffmpeg 命令我半年前在哪台机器上跑过…" 永远找不回来。
而且原生 Ctrl-R 只能子串匹配,搜索体验差。
atuin 把 shell 历史存 SQLite + 加密同步 + 替换 Ctrl-R 为模糊搜索 TUI。
安装
# 一行装
bash <(curl --proto '=https' --tlsv1.2 -sSf https://setup.atuin.sh)
# 或包管理器
brew install atuin
cargo install atuin
# 注册到 shell
atuin init bash >> ~/.bashrc
atuin init zsh >> ~/.zshrc
atuin init fish | source >> ~/.config/fish/config.fish
# 重启 shell
第一次跑
Ctrl-R 不再是 bash 原生 reverse-i-search,而是 atuin 的全屏 TUI:
> ffmpeg
2026-05-20 14:32 ffmpeg -i input.mp4 -vcodec libx264 -crf 23 out.mp4
2025-12-01 09:15 ffmpeg -i src.mov -ss 00:00:05 -t 30 clip.mp4
2025-11-10 21:00 ffmpeg -i in.wav -ab 128k out.mp3
↑↓ 选 | Enter 执行 | Tab 编辑后执行 | Ctrl-D 退出
模糊匹配(不需要前缀完整)、按时间最近排序、显示具体执行时间。
同步到云
atuin 提供免费托管:
atuin register -u myuser -e [email protected] -p 'long-password'
# 服务端发邮件确认
atuin login -u myuser -k <密钥> # 加密 key,重要!
atuin sync
之后每台机器:
atuin login -u myuser -k <密钥>
atuin sync
历史立刻同步过去(端到端加密 —— 服务端只能存 ciphertext)。
密钥(key)丢了等于所有历史丢了——保存到 password manager。
自托管 server
不想用官方 host:
# server 端
docker run -d \
-e ATUIN_DB_URI=postgres://user:pass@host/db \
-p 8888:8888 \
ghcr.io/atuinsh/atuin server start
# 客户端 ~/.config/atuin/config.toml
sync_address = "https://atuin.your-server.com"
配置
~/.config/atuin/config.toml:
# 搜索模式:prefix / fulltext / fuzzy(推荐 fuzzy)
search_mode = "fuzzy"
# 启动时显示历史的 filter
filter_mode = "global" # global | session | host | directory
# 模式:自动按上下文切(按 Tab 切)
filter_mode_shell_up_key_binding = "directory"
# 默认搜索结果数
show_help = true
inline_height = 20
# 不记录某些命令(密码、敏感的)
history_filter = [
"^secret-cmd",
"^export.*PASSWORD",
]
# 不记录这些目录
cwd_filter = [
"/tmp",
]
context-aware 搜索
最强的 feature:按 Tab 切换 filter scope:
global:所有机器所有目录host:仅本机session:仅本 shell sessiondirectory:仅本目录
> docker [filter: directory]
进 ~/projects/myapp 目录搜 docker 只显示在这个目录跑过的 docker
命令。这比 bash Ctrl-R 强 10 倍——找上次"在哪个项目里跑的什么命令"
秒级。
时间过滤
atuin search --before '2 days ago' docker
atuin search --after '1 week ago' kubectl
统计
atuin stats
# Total commands: 12847
# Unique commands: 4321
# Top commands:
# 1. ls (1234)
# 2. cd (987)
# 3. git status (654)
# ...
atuin stats --period 7d # 最近 7 天
发现自己 80% 时间在 cd 和 ls,提示我多用 z + 文件管理器。
导入老历史
atuin import auto # 自动检测 bash/zsh/fish/atuin
之前几年的 ~/.bash_history / ~/.zsh_history 全导入 atuin DB。
不想被记录的命令
# 单条命令前面加空格(bash HISTCONTROL=ignorespace 兼容)
secret-command --token xyz
或者用 atuin 的 history_filter regex。
CLI 用法
atuin history list --limit 50
atuin history list --cwd ~/projects/myapp
atuin search 'docker run'
# 把某条历史拿出来重新跑
atuin search 'ffmpeg' --format '{{ .command }}' --limit 1 | bash
跟 fzf 配合
Ctrl-R 默认是 atuin TUI。如果你更喜欢 fzf:
# atuin 输出 + fzf 渲染
fh() {
atuin history list --format '{{ .timestamp }} | {{ .command }}' \
| fzf --tac --no-sort --tiebreak=index \
--bind 'enter:become(echo {3..})' \
| xargs -I {} bash -c '{}'
}
但 atuin 自带的 TUI 其实 fzf-like,绝大多数场景不需要替换。
性能
10 万条历史的 atuin DB ~ 30 MB;查询 < 50ms。本地纯 Rust + SQLite,
无网络请求。
效果
- 3 台机器历史共享,"半年前那条命令" 永远找得回来
- 搜索体验从 grep-字符串 升到 fuzzy + context-aware
- 在项目目录
Ctrl-R自动过滤到本项目历史,省去大量"误中其它项目命令" - 跨机迁移 / 重装系统 / 新员工 onboarding 都瞬间继承"老司机经验"
踩过的坑
-
加密密钥丢失 = 所有同步历史丢失。注册后立刻
atuin key看
key,存进 password manager 三份(云 + 本地 + 打印)。 -
某些 ZSH 主题与 atuin 冲突:oh-my-zsh 的
Ctrl-R被绑给其它
插件。bindkey '^R' atuin-search强制覆盖。 -
同步把敏感命令也带走:包含
export PASSWORD=xxx/mysql -p xxx
的命令也加密同步。提前用history_filter过滤。 -
服务端不可达时
atuin sync卡:网络问题导致同步 hang。
atuin sync --force或者kill后下次再 sync。 -
新 shell session 启动慢:atuin init 加了几个 hook。如果发现
shell 启动 > 100ms,看看是不是 atuin 同步在做(关auto_sync,手动
atuin sync)。
登录后参与评论。