实时过滤 .bash/zsh_history 中误输入的无效命令,让历史记录更加简洁,便于查找
众所周知,在 Linux shell 中执行过的命令通常会被自动保存至当前用户目录下的 .bash_history
/ .zsh_history
等文件中,可以通过 history
命令查看。命令历史记录对于许多依赖历史命令进行分析和自动补全的 shell 插件是相当重要的。
实际使用过程中,手工键入的命令难免会出现错误,比如偶然打错了命令中的某个字母,导致 command not found。这部分错误的命令就成了命令历史记录中的“脏数据”。我们希望能有一种过滤机制,将这些无效命令从历史记录中剔除。
一种简洁高效的实现方案是:在任意一条命令执行完毕后,读取其返回值,判断命令是否有效(exit status 127 表示 command not found),若无效则将其从历史记录中删除。
我检索了互联网上的相关信息,中文社区内暂时不存在这方面的内容,英文社区内可以找到这样的一篇文章:Avoiding invalid commands in Bash history | boltblog,利用 bash
读取 PROMPT_COMMAND
环境变量的机制实现了上述功能。如果只使用 bash
,只需照搬文中的命令放入 ~/.bashrc
中即可。
但是我发现,这个脚本对于 zsh
并不生效,一是因为 zsh
并不会在每个交互提示信息出现之前执行 ${PROMPT_COMMAND}
中的指令,而是提供了precmd
函数来实现类似的功能;二是 zsh 内建的 history
命令与 bash
有一定差异,比如它不支持通过 history -d
删除单条命令历史记录,而需要使用 fc
命令手动操作历史记录文件(参考 stackexchange)。
鉴于 ${ZSH_VERSION}
(${BASH_VERSION}
) 变量定义与否可以用于判断当前所处的 shell 类型,我将 bash 和 zsh 两种 shell 下实现无效命令历史记录过滤的方案整合为一段脚本:
1 |
|
只需要将上面的代码放入 ~/.bashrc
或 ~/.zshrc
并重启 shell 即可生效。若上一步执行的命令 cmd
无效(not found),shell 将以红色字体提示 Deleted 'cmd' from history.
。