搭建一个“现代”终端环境需要做些什么?
大家好!最近我做了一次终端使用调查,询问大家在使用终端时有哪些困扰。有位读者评论道:
要拥有一个现代的终端体验,需要的东西太多了。真希望这一切都能开箱即用。
我的第一反应是“哦,获得一个现代的终端体验没那么难,你只需要……”,但越想下去,“你只需要……”这个清单就越长,而且我不断想到越来越多的注意事项。
所以我想写下一些笔记,谈谈对我个人而言“现代”终端体验意味着什么,以及我认为是什么让人们难以达到这种状态。
什么是“现代终端体验”?
以下是一些对我来说很重要的东西,以及系统中负责实现它们的部件:
- 支持多行复制粘贴:如果你在 shell 里粘贴了 3 条命令,它不应该立刻把它们全部执行!那太吓人了!(shell、终端模拟器)
- 无限的 shell 历史记录:如果我在 shell 里运行了一条命令,它应该被永久保存下来,而不是在 500 条历史记录之后就被删掉之类的。另外我希望命令在我运行时就立即被写入历史记录,而不是等到退出 shell 会话时才保存(shell)
- 有用的提示符:我的提示符里必须有当前目录和当前 git 分支(shell)
- 24 位色彩:这对我很重要,因为相比只有 256 色的终端,在有 24 位色彩支持的终端里给 neovim 配主题要容易得多(终端模拟器)
- 剪贴板集成:vim 和我的操作系统之间要能互通剪贴板,这样当我在 Firefox 里复制内容后,只需在 vim 里按
p就能粘贴(文本编辑器,可能还包括操作系统/终端模拟器) - 良好的自动补全:比如像 git 这样的命令应该有针对该命令的自动补全(shell)
ls有颜色输出(shell 配置)- 我喜欢的终端主题:我在终端里花了很多时间,我希望它看起来好看,而且它的主题要和我的终端编辑器主题相匹配。(终端模拟器、文本编辑器)
- 自动修复终端状态:如果某个程序打印出一些搞乱我终端的奇怪转义码,我希望它能被自动重置,这样我的终端就不会被弄乱(shell)
- 快捷键绑定:我希望
Ctrl+左方向键能正常工作(shell 或应用程序) - 能在
less这类程序中使用滚轮:(终端模拟器和应用程序)
终端上的便利功能还有千千万万,不同的人看重的东西也不同,但这些是我没有就会非常难受的几项。
我是如何实现“现代体验”的
我的基本做法是:
- 使用
fishshell。基本不做配置,除了:- 把
EDITOR环境变量设置为我最喜欢的终端编辑器 - 把
ls别名为ls --color=auto
- 把
- 使用任何支持 24 位色彩的终端模拟器。过去我用过 GNOME Terminal、Terminator 和 iTerm,但我对此并不挑剔。除了选个字体之外,我基本不做其他配置。
- 使用
neovim,配置是我在过去大约 9 年里慢慢积累起来的(上一次删掉 vim 配置从头开始是 9 年前的事了) - 使用 base16 框架来给所有东西配主题
几个影响我这种做法的因素:
- 我不太经常 SSH 到别的机器上工作
- 我宁愿偶尔用一下鼠标,也不想为每件事都想出纯键盘的操作方式
- 我做的是很多小项目,而不是一个大项目
一些“开箱即用”的“现代”体验方案
如果你想要不错的体验,但又不想花大量时间配置呢?说实话,摸索出一套让我满意的 vim 配置真的花了我差不多十年时间,这可是一段很长的时间!
关于如何用最少的配置获得合理的终端体验,我最好的建议是:
- shell:要么用
fish,要么用搭配 oh-my-zsh 的zsh - 终端模拟器:几乎任何支持 24 位色彩的都行,比如下面这些都很流行:
- linux:GNOME Terminal、Konsole、Terminator、xfce4-terminal
- mac:iTerm(Terminal.app 不支持 256 色)
- 跨平台:kitty、alacritty、wezterm 或 ghostty
- shell 配置:
- 把
EDITOR环境变量设置为你最喜欢的终端文本编辑器 - 也许把
ls别名为ls --color=auto
- 把
- 文本编辑器:这是个难题,也许是 micro 或 helix?我没有认真用过其中任何一个,但它们看起来都是非常酷的项目,而且我觉得很神奇的是,在 micro 里你可以直接使用所有常见的 GUI 编辑器命令(
Ctrl-C复制、Ctrl-V粘贴、Ctrl-A全选),并且它们的表现正如你所期望的那样。我可能会试着切换到 helix,只是重新训练我的 vim 肌肉记忆似乎太难了。另外 helix 目前还没有 GUI 和插件系统。
就我个人而言,我不会用 xterm、rxvt 或 Terminal.app 作为终端模拟器,因为我过去发现它们缺少一些核心特性(比如 Terminal.app 缺少 24 位色彩),这会让终端对我来说更难用。
不过我也不想把获得“现代”终端体验这件事说得比实际更容易——我认为有两个问题让它变得困难。我们来聊聊吧!
通往“现代”体验的问题一:shell
bash 和 zsh 是目前最受欢迎的两个 shell,而它们的默认体验都不符合我的要求,例如:
- 你需要自定义提示符
- 它们默认不带 git 补全,你得自己配置
- 默认情况下,bash 只保存 500 条(!)历史记录,而 zsh(至少在 Mac OS 上)只配置为保存 2000 条,这也仍然不算多
- 我觉得 bash 的 Tab 补全非常令人沮丧,如果匹配项不止一个,你就无法用 Tab 在它们之间切换
尽管我很喜欢 fish,但它不兼容 POSIX 这一事实确实让很多人难以切换过去。
当然,学会在 bash 或其他 shell 里自定义提示符是完全可能的,甚至不需要多复杂(在 bash 里我大概会从类似 export PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ ' 的东西开始,或者使用 starship)。但每一件这些“不复杂”的事情加起来真的很可观,尤其是当你需要在多个系统之间保持配置同步的时候就更难了。
获得“现代” shell 体验的一个极其流行的解决方案是 oh-my-zsh。它看起来是个很棒的项目,我也知道很多人用得很开心,但我过去在这类配置系统上吃过苦头——看起来现在基础的 oh-my-zsh 会增加大约 3000 行配置,而我常常发现,多一层配置系统会让出错时的问题排查变得更难。我个人有个倾向:用这类系统添加一堆额外的插件,让系统变慢,然后因为慢而恼火,最后把它整个删掉,从头写一份新配置。
通往“现代”体验的问题二:文本编辑器
在我最近做的终端调查中,最受欢迎的终端文本编辑器毫无疑问是 vim、emacs 和 nano。
我认为终端文本编辑器的主要选择有:
- 使用 vim 或 emacs 并按自己的喜好配置,只要你肯下功夫,基本上想要什么功能都能有
- 使用 nano 并接受体验会比较有限的事实(比如我觉得在 nano 里没法用鼠标选中文字然后“剪切”)
- 使用
micro或helix,它们似乎提供了相当不错的开箱即用体验,但作为不那么主流的文本编辑器,偶尔可能会遇到一些问题 - 尽量完全避免使用终端文本编辑器,比如用 VSCode,用 VSCode 的内置终端满足所有终端需求,基本从不在终端里编辑文件。或者我知道有很多人在终端里把
code设为他们的EDITOR。
问题三:单个应用程序
最后一个问题是,有时候我用的一些程序本身就挺烦人的。比如在我的 Mac OS 机器上,/usr/bin/sqlite3 不支持 Ctrl+左方向键 这个键盘快捷键。修复这个问题以在 SQLite 中获得合理的终端体验有点复杂,我不得不:
- 弄清楚为什么会这样(Mac OS 不附带 GNU 工具,而“Ctrl-左方向键”的支持来自 GNU readline)
- 找到一个变通办法(通过 homebrew 安装 sqlite,它带有 readline 支持)
- 调整我的环境(把 Homebrew 的 sqlite3 加入我的 PATH)
我发现调试这类特定于应用程序的问题真的不容易,而且常常让人觉得“不值得”——很多时候我最后就是忍受各种小不便,因为我不想花几个小时去调查它们。我能把这个问题的来龙去脉搞清楚,唯一的原因是我最近花了大量时间研究终端。
使用终端程序获得“现代”体验的一个重要部分,其实就是使用更新的终端程序。比如我懒得去学在 top 里对列排序的快捷键,但在 htop 里我可以直接用鼠标点击列标题来排序。所以我改用 htop 了!但是发现新的更“现代”的命令行工具并不容易(虽然我在这里列了一个清单),找到自己实际用起来喜欢的工具也需要时间,而且如果你 SSH 到另一台机器上,那些工具不一定在那里。
一切都相互影响
我发现配置终端让一切变得“美好”时的一个棘手之处在于:改变工作流中一件看似很小的事情,真的会影响到其他一切。比如我现在不用 tmux。但如果我又需要用 tmux 了(比如因为我需要大量 SSH 到另一台机器上工作),我就得考虑几件事,比如:
- 如果我想让 tmux 的复制操作通过 SSH 与系统剪贴板同步,我就得确保我的终端模拟器支持 OSC 52
- 如果我想用 iTerm 的 tmux 集成(它会把 tmux 的标签页变成 iTerm 的标签页),我就得改变配置颜色的方式——现在我是用一个在 shell 启动时运行的shell 脚本来设置颜色的,但这意味着恢复 tmux 会话时颜色就丢了。
可能还有更多我没想过的事情。“用 tmux 意味着我必须改变管理颜色的方式”听起来不太可能,但这真的发生在我身上,于是我决定:“好吧,我现在不想改变管理颜色的方式,所以我就不用那个功能了!”
记住自己依赖哪些特性也很难——比如也许我现在的终端确实支持 OSC 52,但因为通过 SSH 从 tmux 复制一直都能正常工作,我甚至没意识到这是我需要的东西,然后当我换终端时它就莫名其妙地失效了。
慢慢改变
就我个人而言,虽然我觉得我的配置并不算特别复杂,但我花了 20 年才走到今天这一步!因为终端配置的改动很容易产生意想不到且难以理解的后果,我发现如果一次性改动大量终端配置,一旦出问题就很难弄清哪里出了错,这会让人非常迷失方向。
所以我通常倾向于做比较小的改动,并接受有些改动可能需要很长很长的时间才能适应。比如我一两年前从 ls 切换到了 eza,虽然我喜欢它(因为 eza -l 默认打印人类可读的文件大小),但我至今仍不太确定是否满意。不过有时候做一个大改动也是值得的,比如我 10 年前从 bash 切换到了 fish,我非常庆幸自己做了这个决定。
获得一个“现代”终端并没有那么容易
试图解释配置终端有多“容易”,反而让我意识到这事其实挺难的,而且我有时依然会感到困惑。
我发现,在终端里从来没有一种完美的配置方式能与其他所有东西都兼容。我只能不断尝试,找到某种对我而言局部稳定的状态,并接受这样一个事实:如果我开始使用一个新工具,它可能会打乱整个系统,我可能需要重新思考一些事情。
随机一篇博客