Zellij 的会话复活(Session Resurrection)功能是其区别于许多其他终端复用器的一大亮点。当你的机器意外重启、终端崩溃或者会话进程被终止时,Zellij 能够从之前保存的状态中恢复整个工作环境——包括面板布局和其中运行的命令。本文将详细介绍会话复活的机制、配置方法以及多会话管理技巧。
一、会话复活机制
Zellij 默认包含会话复活功能,无需额外安装插件。其核心原理是定期将会话状态序列化(serialize)到磁盘上,形成一份快照。当会话意外退出后,你可以通过 attach 命令恢复它,Zellij 会读取快照并重建之前的布局和命令。
序列化的工作方式如下:
- Zellij 每隔
serialization_interval秒(默认 1 秒)自动序列化一次当前会话状态。 - 序列化结果保存为人类可读的 KDL 布局文件,存放在会话数据目录中。
- 由于是 KDL 格式,你可以用文本编辑器打开查看甚至手动编辑保存的布局。
这种定期快照机制确保了即使会话突然中断,你丢失的最多也只是一秒钟的状态变化。
二、序列化内容
会话序列化会保存哪些内容取决于你的配置。默认情况下,Zellij 会保存以下信息:
- 会话布局:所有标签页和面板的排列结构,包括分割方向、比例关系等。
- 每个面板运行的命令:记录每个面板中正在执行的外部命令(如
vim、htop、python script.py等)。
此外,你还可以通过配置启用更多内容的保存:
- 面板视口内容:通过设置
pane_viewport_serialization true,保存每个面板当前可见区域的内容。 - 回滚缓冲区:通过
scrollback_lines_to_serialize选项指定保存多少行的回滚历史。例如设置为10000会保存每个面板最近 10000 行的输出历史。
启用回滚缓冲区保存会增加快照文件的大小和序列化耗时,建议根据实际需要权衡。对于大多数开发场景,保存命令和布局已经足够。
三、安全机制
直接自动重新执行之前运行的命令可能存在安全风险。例如,保存的命令可能包含敏感信息,或者在会话中断期间环境发生了变化。为此,Zellij 在复活会话时采用了安全的交互方式:
当你恢复一个已退出的会话时,Zellij 不会立即运行之前保存的命令。取而代之的是,在每个需要运行命令的面板中显示如下提示:
Press ENTER to run: vim main.py
用户需要手动按 Enter 确认才会执行该命令。这样你可以在执行前检查每个命令是否安全、是否仍然需要运行。
如果你完全信任保存的命令(例如在受控的开发环境中),可以使用 --force-run-commands 选项跳过确认提示:
zellij attach my-session --force-run-commands
此选项会自动执行所有面板中之前运行的命令,无需逐一确认。适合在自动化脚本和 CI 环境中使用。
四、配置会话复活
在 config.kdl 中,以下选项与会话复活相关:
| 配置项 | 默认值 | 说明 |
|---|---|---|
session_serialization |
true |
是否启用会话序列化。设为 false 则完全禁用复活功能 |
pane_viewport_serialization |
true |
是否保存面板可视区域的内容 |
scrollback_lines_to_serialize |
10000 |
保存的回滚缓冲区行数 |
serialization_interval |
1(秒) |
自动序列化的间隔时间 |
auto_layout |
true |
复活时是否自动应用保存的布局 |
配置示例:
// ~/.config/zellij/config.kdl
session_serialization true
pane_viewport_serialization true
scrollback_lines_to_serialize 10000
serialization_interval 2
auto_layout true
自定义命令发现:post_command_discovery_hook
默认情况下,Zellij 只能序列化它知道的外部命令。但对于某些特殊场景(例如通过包装脚本启动的程序),Zellij 可能无法正确识别实际运行的命令。post_command_discovery_hook 允许你自定义命令发现的逻辑。
该选项接受一个 shell 命令字符串,Zellij 会在每个面板中执行它来获取正在运行的命令:
// 使用自定义脚本发现命令
post_command_discovery_hook "/path/to/my-discovery-script.sh"
这个功能在以下场景中特别有用:
- 你使用自定义的 shell wrapper 来启动程序。
- 需要捕获比默认更详细的命令上下文信息。
- 需要在命令发现过程中执行额外的过滤或转换逻辑。
五、恢复与管理会话
命令行恢复
当一个会话退出后(无论是正常退出还是意外崩溃),你可以使用 attach 命令恢复它:
zellij attach my-session
Zellij 会读取该会话的序列化快照,重建布局并提示你确认运行之前的命令(除非使用了 --force-run-commands)。
通过会话管理器恢复
你也可以通过 Zellij 内置的会话管理器来恢复已退出的会话:
- 在 Zellij 中按
Ctrl+s进入 Session 模式。 - 按
w打开会话管理器。 - 按
Tab键切换到 EXITED 标签页。 - 使用方向键选择要恢复的会话,按
Enter恢复。
会话管理器将已退出的会话和活跃的会话分开展示,让你一目了然地管理所有会话。
手动保存
除了自动定期序列化,你还可以随时手动保存当前会话:
zellij action save-session
这在以下场景中很有用:
- 即将进行系统维护或升级,想确保当前状态已保存。
- 对布局做了重要调整后,想立即创建快照。
- 准备共享会话布局给团队成员。
删除会话布局
当不再需要某个已退出会话的快照时,可以删除它以释放磁盘空间:
# 删除指定会话的布局
zellij delete-session my-session
# 删除所有已退出会话的布局
zellij delete-all-session-layouts
六、多会话管理
在实际工作中,你可能同时运行多个会话——例如一个用于前端开发、一个用于后端服务、一个用于监控日志。Zellij 提供了完整的多会话管理命令。
列出所有会话
zellij ls
输出会显示所有会话的名称和状态(运行中或已退出),帮助你快速了解当前的工作环境。
终止会话
当某个会话不再需要时,可以将其终止:
# 终止指定会话
zellij kill-session my-session
# 终止所有会话
zellij kill-all-sessions
# kill-all-sessions 的简写
zellij ka
终止会话会立即结束该会话中的所有进程,并删除运行时数据(但序列化快照仍会保留,除非你同时使用 delete-session)。
切换会话
在 Zellij 内部,你可以无需分离再重新连接就能切换到另一个会话:
zellij action switch-session my-session
这会立即切换到指定的会话。当前会话会自动分离并在后台继续运行。你也可以通过会话管理器(Ctrl+s → w)以交互方式选择要切换的会话。
升级 Zellij 不丢失会话
当 Zellij 版本升级后,序列化格式可能发生变化。Zellij 团队尽力保持向后兼容,但如果你遇到旧会话无法恢复的情况,可以:
- 查看保存的 KDL 布局文件,手动调整格式后加载。
- 使用
zellij setup --check检查配置和布局文件的兼容性。 - 在升级前手动备份会话数据目录(通常位于
~/.local/share/zellij/)。
通过合理使用会话复活和多会话管理功能,你可以构建一个稳定、高效的终端工作流,不再担心意外中断带来的工作损失。