Atuin 历史清理命令 `atuin history prune` 完全指南:基于 history_filter 的批量删除与 dry-run 演练
2026/9/19 23:28:05 网站建设 项目流程

Atuin 历史清理命令atuin history prune完全指南:基于 history_filter 的批量删除与 dry-run 演练

【免费下载链接】atuin✨ Making your shell magical项目地址: https://gitcode.com/gh_mirrors/at/atuin

本指南聚焦 Atuin 的atuin history prune命令,讲解它如何根据history_filtercwd_filter等排除过滤器,批量删除已记录但不符合当前过滤规则的历史条目,并介绍--dry-run-n)安全预览机制。读完本文,你将掌握在调整过滤配置后如何安全、可回查地清理旧历史记录,并理解其底层判定逻辑(基于crates/atuin/src/command/client/history.rscrates/atuin-client/src/history.rs)。

一、atuin history prune是什么

atuin history prune是 Atuin 客户端提供的一条子命令,其核心作用非常明确:删除与history_filter配置参数相匹配的历史条目

它针对的是这样一类场景:某条命令在保存时并不违反当时的过滤规则(或当时还没有配置过滤规则),因此被写入了本地历史数据库;但现在history_filter已经把它列入了排除名单。这类"历史遗留"条目不会自动消失——过滤规则只对今后新记录的命令生效,对已经落库的旧条目无能为力,prune正是用来弥补这一空白的清理工具。

在 Atuin 命令体系里,Prune变体与Dedup(去重)等一同定义在HistoryCmd枚举中,其命令文档注释为 "Delete history entries matching the configured exclusion filters"(删除与已配置排除过滤器匹配的历史条目),见 crates/atuin/src/command/client/history.rs。

二、为什么需要 prune:过滤规则只向前生效

理解prune的最佳方式,是先理解 Atuin 的过滤机制。Atuin 提供了多层"不记录"手段(详见 排除命令指南):

手段配置项 / 操作生效时机
命令前加空格Shell 的 ignorespace 约定输入时
正则过滤命令history_filter记录时
正则过滤目录cwd_filter记录时
敏感信息自动过滤secrets_filter(默认开启)记录时

关键在于:这些过滤都发生在"记录时"(write-time)。当你新加一条history_filter规则后,Atuin 会立即拒绝后续匹配的命令入库,但数据库中早已存在的旧条目不会被追溯处理。正如文档所描述的:"These may be commands that match the currenthistory_filterconfiguration, but were saved to history before the filter excluded them."(这些可能是与当前history_filter配置匹配、但在过滤器将其排除之前就已保存的命令。)

因此官方文档给出的建议是:在更新history_filter之后,运行 prune 命令以移除与新过滤器匹配的旧历史条目。这个场景在 delete-history 指南 与 config 参考 中均有呼应:

After updating that parameter, you can run the prune command to remove old history entries that match the new filters.

三、快速上手:先预览,再删除

atuin history prune的使用非常直接,官方推荐的工作流是"两步走":

# 第一步:预览。列出会被删除的历史条目,但实际不执行删除 atuin history prune --dry-run # 第二步:确认无误后,真正执行删除 atuin history prune

在 delete-history 指南 中同样演示了这一流程:先用--dry-run预览将被移除的内容,再执行真正的删除。

参数一览

atuin history prune接受的全部参数如下(与 reference/prune.md 保持一致):

参数说明
--dry-run/-n仅列出匹配的历史行,不执行实际删除

在源码层面,该参数定义于 crates/atuin/src/command/client/history.rs:

/// Delete history entries matching the configured exclusion filters Prune { /// List matching history lines without performing the actual deletion. #[arg(short = 'n', long)] dry_run: bool, },

四、底层原理:prune 到底做了什么

atuin history prune的执行逻辑集中在handle_prune函数中(crates/atuin/src/command/client/history.rs),整体可分为三个阶段:

1. 扫描并筛选(匹配判定)

let matches: Vec<History> = db .list([Global], &context, None, false, false, None) .await? .into_iter() .filter(|h| !h.should_save(settings)) .collect();

prune 会从本地 SQLite 数据库列出全部历史条目(全局范围),然后逐条调用History::should_save(settings)判断"这条命令在当前配置下是否应该被保存"。凡是should_save返回false的条目,就是 prune 的清理对象。源码注释也明确指出:"Grab all executed commands and filter them usingHistory::should_save."(取出所有执行过的命令并用should_save过滤。)

2. 判定规则的真相:不只是 history_filter

should_save的定义位于 crates/atuin-client/src/history.rs:

pub fn should_save(&self, settings: &Settings) -> bool { !(self.command.starts_with(' ') || self.command.is_empty() || settings.history_filter.is_match(&self.command) || settings.cwd_filter.is_match(&self.cwd) || (settings.secrets_filter && contains_secret(&self.command))) }

由此可以明确:一条历史条目会被 prune 判定为"不应保存"(即会被删除),只要满足以下任一条件:

条件说明
命令以空格开头符合 ignorespace 约定(多数 shell 不会把它交给 Atuin,但历史遗留数据可能仍存在)
命令为空字符串空条目
命令匹配history_filter见下文配置详解
命令所在目录匹配cwd_filter目录级过滤
开启secrets_filter且命令包含敏感信息内置的凭据正则匹配

这意味着prune实际清理的范围比history_filter更广——cwd_filtersecrets_filter判定失败的条目同样会被一并清理。这一点在 排除命令指南 中也有印证:

This deletes existing entries matching your currenthistory_filterandcwd_filter.

3. 执行删除(或仅打印)

筛选完成后:

  • 若无匹配条目,输出No entries to prune.
  • 若有 1 条,输出Found 1 entry to prune.;多条则输出Found {n} entries to prune.
  • dry-run 模式:调用print_list以人类可读格式(ListMode::Human,遵循settings.history_formatsettings.timezone)打印所有将被删除的条目,不做任何数据库修改;
  • 实际执行模式:先加载或生成本地加密密钥(paseto_v4::Key::try_load_or_generate(&settings.key_path)),取得主机 ID 并构造HistoryStore,随后对每条匹配条目在 stderr 打印deleting {entry.id},最后调用delete_history_entries完成删除(该函数同时处理本地库删除与记录存储删除,保证后续同步一致性)。

由此可见,prune 是本地与记录存储协同的删除操作,而非简单的 SQL DELETE。

五、配套配置详解:history_filtercwd_filter

要发挥 prune 的价值,先要正确配置过滤规则。

history_filter

~/.config/atuin/config.toml中配置,用于从历史跟踪中排除匹配的命令(config 参考):

## 注意:这些正则表达式是未锚定的, ## 即如果不以 ^ 开头或以 $ 结尾,它们将匹配命令中的任何位置。 history_filter = [ "^secret-cmd", "^innocuous-cmd .*--secret=.+" ]

它支持正则表达式,可以精细控制。再如 排除命令指南 中的示例:

history_filter = [ "^ls$", # 排除裸 'ls',但保留 'ls -la' "^cd ", # 排除所有 cd 命令 "--password", # 排除任何带 password 标志的命令 ]

cwd_filter

按工作目录排除(config 参考):

## 同样支持未锚定的正则表达式,匹配的是目录路径 cwd_filter = [ "^/tmp", # 排除在 /tmp 下执行的所有命令 "/node_modules/", # 排除在任何 node_modules 目录内执行的命令 "^/home/user/scratch", # 排除某个 scratch 目录 ]

配置更新后,cwd_filter匹配的历史遗留条目同样需要通过atuin history prune追溯清理。

六、典型实战场景与注意事项

场景一:为history_filter新增规则后清理存量

假设你最近决定把所有aws命令排除出历史,于是在config.toml中追加了"^aws"。此后新执行的aws命令不再入库,但过去几个月积累的aws条目仍占据搜索索引与存储空间。此时:

atuin history prune --dry-run # 逐条核对将要删除的条目 atuin history prune # 执行清理

场景二:只想删除少量条目

prune是"按过滤器批量清理"的专用工具。如果你只想删除个别历史条目而保留其余内容,官方建议改用atuin search --delete进行交互式删除(见 delete-history 指南),两者定位不同,可按需组合。

场景三:与同步的关系

prune 通过delete_history_entries同时处理本地数据库与记录存储,删除操作会进入 Atuin 的记录同步体系,因此在多机同步场景下,其他设备可通过常规同步机制收敛这些删除。若需要彻底重置账号数据(清空服务端全部历史),则应参考 delete-history 指南 中的账号重置流程,而不是 prune。

注意事项

  • 过滤规则只向前生效:任何对history_filter/cwd_filter的修改都不会自动影响既有数据,必须显式运行 prune(排除命令指南);
  • --dry-run是安全阀:批量删除前务必先用-n预览,确认删除范围符合预期,再执行真实删除;
  • secrets_filter默认开启:即使你没有配置任何过滤规则,内置凭据过滤(如 AWS Key、GitHub Token、Slack webhook 等,详见 config 参考 的完整清单)判定失败的旧条目也在 prune 的清理范围内。

七、小结

atuin history prune是 Atuin 历史管理体系中与history_filter等排除过滤器配套的"事后清理"命令:

  • 职责单一:删除已记录但按当前配置不应保存的历史条目;
  • 操作安全--dry-run/-n支持先预览后删除;
  • 判定透明:底层复用History::should_save的统一判定逻辑,覆盖空格前缀、空命令、history_filtercwd_filtersecrets_filter五类情形(crates/atuin-client/src/history.rs);
  • 流程闭环:修改过滤配置 → 运行--dry-run核对 → 正式 prune → 后续通过同步机制收敛删除。

如果你希望进一步了解与 prune 相邻的历史管理命令,可以继续阅读 history 相关参考文档 中的atuin history list,或查阅 delete-history 指南 了解其他删除方式(如atuin search --delete、账号重置)之间的差异与适用场景。

【免费下载链接】atuin✨ Making your shell magical项目地址: https://gitcode.com/gh_mirrors/at/atuin

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询