【译文】Shell 历史记录是您最好的生产力工具
如果你经常使用 shell/终端,那么随着时间的推移,历史记录就会成为你的个人知识库、文档和命令参考。高效地使用这些个人文档可以大大提高你的工作效率。因此,这里有几个关于如何优化 shell 历史记录配置和使用的小技巧,让你的 shell 历史记录发挥最大作用。
配置
我使用的是 ZSH 和 Oh My Zsh,因此本文的提示将侧重于 ZSH,但 Bash 或其他 shell 也能达到类似效果。
如果你正在使用 Bash,并希望切换到 ZSH,或尝试下面的示例,请查看本文。
说完这些,让我们从配置选项开始,这些选项将帮助我们充分利用保存的历史记录:
# ~/.zshrc
# ...
HISTFILE="$HOME/.zsh_history"
HISTSIZE=10000000
SAVEHIST=10000000
HISTORY_IGNORE="(ls|cd|pwd|exit|cd)*"
如果不保存/保留历史数据,我们就无法有效地搜索和使用历史记录。通过上述配置,我们可以存储几乎无限量的命令历史记录。此外,它还使用 HISTORY_IGNORE
列出了不会保存在历史记录中的 ls
、cd
等命令,你可以根据自己的喜好调整忽略列表。
为了进一步优化配置,我们可以添加以下 ZSH 选项:
# ~/.zshrc
# https://zsh.sourceforge.io/Doc/Release/Options.html (16.2.4 History)
setopt EXTENDED_HISTORY # 以":start:elapsed;command "格式写入历史文件。
setopt INC_APPEND_HISTORY # 立即写入历史文件,而不是在 shell 退出时写入。
setopt SHARE_HISTORY # 在所有会话之间共享历史记录。
setopt HIST_IGNORE_DUPS # 不要再次记录刚刚记录过的事件。
setopt HIST_IGNORE_ALL_DUPS # 如果新事件与旧事件重复,则删除已记录的旧事件。
setopt HIST_IGNORE_SPACE # 不要记录以空格开头的事件。
setopt HIST_SAVE_NO_DUPS # 不要将重复事件写入历史文件。
setopt HIST_VERIFY # 不要在历史展开时立即执行。
setopt APPEND_HISTORY # 附加到历史文件(默认)
setopt HIST_NO_STORE # 不要存储历史命令
setopt HIST_REDUCE_BLANKS # 删除添加到历史记录中的每行命令中多余的空白。
以上主要是配置 ZSH 忽略某些命令,以避免造成历史记录混乱,例如重复命令或历史命令。它还会为每条命令添加时间戳,这在搜索时会很方便(见下一节)。
我想在此强调的一个特殊选项是 HIST_IGNORE_SPACE
,如果你想避免在历史记录中存储秘密,这个选项非常有用–只需在任何包含秘密/密码的命令前加上空格,例如 export AWS_ACCESS_KEY_ID=...
(注意 export
前的空格),它就不会出现在历史记录中。
前面的选项配置了历史记录的存储方式,现在我们来谈谈如何配置历史记录的搜索和展示方式。
默认情况下,只能通过精确匹配进行搜索,但 ZSH 包含一个插件,可以使用模糊搜索进行搜索。要启用它,我们只需添加该插件:
# ~/.zshrc
# ...
plugins=(git fzf)
这样,在搜索历史记录时,ZSH 会自动使用 FZF 进行模糊搜索。不过,这可能会在后台使用查找命令,速度不是很快。因此,为了提高性能(对于超大历史文件),我建议使用 ag
:
sudo apt-get install silversearcher-ag
# add to # ~/.zshrc
export FZF_DEFAULT_COMMAND='ag --hidden -g ""'
最后一个配置选项是历史时间戳格式化–默认情况下,查看history
记录时会得到类似的输出结果:
10206 echo hello
10207 head some-file.txt
10208 curl google.com
10209 cat some-file.txt
即历史文件中的行号和命令本身。不过,通过在 ~/.zshrc
中添加 HIST_STAMPS="yyyy-mm-dd"
,我们可以得到如下结果:
10206 2024-03-30 12:29 echo hello
10207 2024-03-30 12:51 head some-file.txt
10208 2024-03-30 13:21 curl google.com
10209 2024-03-30 14:15 cat some-file.txt
搜索
现在我们已经配置好了一切,让我们看看如何有效地搜索所有历史记录。
最简单的方法是使用history
命令,而不需要键盘绑定。不过,只使用 history
命令会转储整个历史文件,这并不实用,我们可以使用:
\history -E -10
10206 30.3.2024 12:29 echo hello
10207 30.3.2024 12:51 head some-file.txt
10208 30.3.2024 13:21 curl google.com
10209 30.3.2024 14:15 cat some-file.txt
...
\history -i
10206 2024-03-30 12:29 echo hello
10207 2024-03-30 12:51 head some-file.txt
10208 2024-03-30 13:21 curl google.com
10209 2024-03-30 14:15 cat some-file.txt
...
fc -E -l -10
10206 30.3.2024 12:29 echo hello
10207 30.3.2024 12:51 head some-file.txt
10208 30.3.2024 13:21 curl google.com
10209 30.3.2024 14:15 cat some-file.txt
...
我们可以使用 -<N>
标志来指定 history
和 fc
命令的行数。此外,-E
和 -i
还会给出不同的日期格式。
如果想编辑并重新执行最后一条命令,也可以使用不带参数的 fc
命令–它会打开默认编辑器,在其中编辑命令,关闭编辑器后,命令将被执行。
另一个有用的命令是 r
,它可以在不编辑的情况下重新执行最后一条命令(如!!
);r <WORD>
,它可以执行包含 WORD
字符串的最后一条命令。
不过大多数情况下,我们都希望使用键绑搜索历史记录–在 ZSH 中,默认的 CTRL+R
将为你提供基于上下文的历史滚动(历史小工具):
如您所见,这也包括 FZF 模糊搜索。
如果由于某种原因在您的机器上无法使用,请检查键盘绑定:
bindkey | grep fzf-history-widget
"^R" fzf-history-widget # ^R is CTRL+R
如果你更喜欢经典的反向搜索,而不是基于上下文的历史滚动,那么你可以绑定 history-incremental-search-backward
和 history-incremental-search-forward
事件:
# Add to ~/.zshrc
bindkey "^E" history-incremental-search-backward # CTRL+E
bindkey "^S" history-incremental-search-forward # CTRL+S
你也可以直接开始键入命令,然后按向上/向下箭头搜索历史记录,同时考虑到命令行中键入的内容:
文档中也有更多的变种,例如:
history-beginning-search-backward
history-beginning-search-backward-end
history-search-backward
...
请注意,不同的操作系统可能会使用不同的关键字符,例如,在不同的系统中,向上箭头可以是 \e[A
、^[OA
或 ^[[A
。
你可能已经从上面的 GIF 中注意到,你可以为这种经典的反向搜索设置语法高亮,只需安装 zsh-syntax-highlighting
即可:
sudo apt-get install zsh-syntax-highlighting
echo "source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ${ZDOTDIR:-$HOME}/.zshrc
同步
要想更上一层楼,在不同的工作站上都能随时随地查看 shell 历史记录,还可以使用 history-sync
插件,该插件使用 Git 跨工作站同步历史记录 – 有关工作原理和设置方法,请参阅插件文档。
除了上述同步功能外,atuin.sh 也是一个更现代的选择,它使用 SQLite 作为存储空间并支持 ZSH,有关功能和详情,请参阅网站。
结论
在这一点上,我非常确定,如果我丢失了 .zsh_history
我可能就再也无法完成我的工作了。我运行的大多数命令其实都是 CTRL+R
加上一些小的编辑。
因此,希望通过上述提示和配置,你的 shell 历史记录能成为你的个人知识库,并帮助你提高 shell 使用效率。
注:我完整的 ~/.zshrc
(去掉注释)可在以下 gist 中找到。
本文文字及图片出自 Shell History Is Your Best Productivity Tool
你也许感兴趣的:
- 7 个非常实用的 Shell 拿来就用脚本实例!
- zsh取代bash 成为macOS Catalina的默认shell
- 在 Linux 中使用 bd 命令快速返回到特定的父目录
- 浅析Bash中的 {花括号}
- 写好shell脚本的13个技巧
- 数据科学家的命令行技巧
- 写好shell脚本的13个技巧
- 10个有趣的Linux命令和Shell 脚本
- 程序员必知必会的那些邪恶的脚本
- Shell中$()、$(())和${}的用法
你对本文的反应是: