前文介绍了 zellij action 的各种子命令,本文将进入脚本编程的领域。通过 subscribe 实时监控面板事件、watch 只读监视会话,以及将 action 命令组合成完整的自动化脚本,你可以让 Zellij 成为 CI 流水线、多步骤工作流和后台任务管理的强大平台。
一、zellij subscribe 实时监控
zellij subscribe 是 Zellij 脚本编程的核心工具,它可以实时输出面板的事件流,包括终端输出、退出事件、焦点变化等。
基本用法
zellij subscribe --pane-id <面板ID> <事件类型>
监控指定面板的终端输出:
zellij subscribe --pane-id 1 terminal_1
这会持续输出面板 1 的所有终端数据(包括 ANSI 转义序列),直到你手动中断。
选项
| 选项 | 说明 |
|---|---|
-p / --pane-id <id> | 指定要监控的面板 ID |
-s / --session-name <名称> | 指定目标会话名称 |
-f / --history | 包含历史输出(从面板创建开始的完整输出) |
--ansi | 保留 ANSI 转义序列(默认会剥离) |
JSON 输出模式与 jq 过滤
subscribe 的输出可以配合 jq 进行结构化过滤:
# 监控面板输出并过滤 JSON
zellij subscribe --pane-id 1 terminal_1 | \
jq -r '.data' | grep "ERROR"
# 只提取退出事件
zellij subscribe --pane-id 1 pane_exited | \
jq -r '.exit_status'
常用的事件类型包括:
- terminal_1:面板的终端输出流
- pane_exited:面板中进程退出的通知
- focus:面板获得或失去焦点
监控其他会话和多个面板
使用 -s 选项可以监控其他会话中的面板:
zellij subscribe -s ci-session --pane-id 3 terminal_1
要同时监控多个面板,可以在后台运行多个 subscribe 进程:
#!/bin/bash
zellij subscribe --pane-id 1 terminal_1 > /tmp/pane1.log &
zellij subscribe --pane-id 2 terminal_1 > /tmp/pane2.log &
wait
二、zellij watch 只读监视
zellij watch 提供了一种更简单的只读监视方式,可以直接查看指定会话的实时状态:
zellij watch my-session-name
这个命令会以只读方式连接到指定会话,你可以看到面板的实时输出,但不能进行任何操作。它非常适合在不干扰工作流的情况下查看 CI 构建进度或监控后台任务。
三、脚本编程实例
CI 流水线脚本
以下脚本演示如何用 Zellij 构建一个简单的 CI 流水线:在一个会话中依次运行构建、测试、部署,并根据每一步的结果决定是否继续:
#!/bin/bash
set -euo pipefail
SESSION="ci-pipeline"
zellij -s "$SESSION" -d # 创建分离会话
# 第一步:构建
zellij action -s "$SESSION" run -n "构建" --blocking -- cargo build --release
if [ $? -ne 0 ]; then
echo "构建失败,终止流水线"
zellij kill-session "$SESSION"
exit 1
fi
# 第二步:测试
zellij action -s "$SESSION" run -n "测试" --blocking -- cargo test
if [ $? -ne 0 ]; then
echo "测试失败,终止流水线"
zellij kill-session "$SESSION"
exit 1
fi
# 第三步:部署
zellij action -s "$SESSION" run -n "部署" --blocking -- ./deploy.sh
echo "流水线执行完毕"
# 保存会话并分离
zellij kill-session "$SESSION"
多步骤人工干预工作流
有些工作流需要人工确认后才能继续。以下脚本创建一个面板等待用户输入,然后根据输入决定下一步操作:
#!/bin/bash
set -euo pipefail
SESSION="deploy-workflow"
zellij -s "$SESSION" -d
# 在面板中显示部署信息,等待用户确认
zellij action -s "$SESSION" run -n "确认部署" -- \
bash -c 'read -p "确认部署到生产环境?(y/N): " confirm; \
[ "$confirm" = "y" ] && echo "CONFIRMED" || echo "CANCELLED"'
# 等待并检查输出
sleep 2
OUTPUT=$(zellij action -s "$SESSION" dump-screen)
if echo "$OUTPUT" | grep -q "CONFIRMED"; then
zellij action -s "$SESSION" run -n "部署中" -- ./deploy-prod.sh
else
echo "部署已取消"
zellij kill-session "$SESSION"
exit 0
fi
Git 状态覆盖面板
使用浮动面板在屏幕角落显示实时 Git 状态:
#!/bin/bash
# git-overlay.sh — 在浮动面板中显示 Git 状态
zellij run -f \
--x "75%" --y "65%" \
--width "25%" --height "30%" \
-n "Git Status" \
-- bash -c 'while true; do
clear
echo "=== Git Status ==="
echo ""
git status -s
echo ""
echo "=== Recent Commits ==="
git log --oneline -5
echo ""
echo "=== Branch ==="
git branch -v
sleep 5
done'
资源监控覆盖面板
类似的思路,创建一个资源监控浮动面板:
#!/bin/bash
# resource-monitor.sh — 在浮动面板中监控系统资源
zellij run -f \
--x 0 --y "70%" \
--width "30%" --height "28%" \
-n "监控" \
-- bash -c 'while true; do
clear
echo "=== CPU ==="
top -bn1 | head -3
echo ""
echo "=== Memory ==="
free -h
echo ""
echo "=== Disk ==="
df -h / | tail -1
sleep 3
done'
后台任务管理模式
以下脚本展示如何创建一个后台任务管理面板,在后台运行长时间任务并记录日志:
#!/bin/bash
set -euo pipefail
SESSION="tasks"
LOG_DIR="/tmp/zellij-tasks"
mkdir -p "$LOG_DIR"
# 创建会话
zellij -s "$SESSION" -d
# 后台任务 1:编译
zellij action -s "$SESSION" run -n "编译" -- \
bash -c 'cargo build --release 2>&1 | tee /tmp/zellij-tasks/build.log; \
echo "BUILD_DONE" >> /tmp/zellij-tasks/build.log'
# 后台任务 2:文档生成
zellij action -s "$SESSION" run -n "文档" -- \
bash -c 'cargo doc --no-deps 2>&1 | tee /tmp/zellij-tasks/doc.log; \
echo "DOC_DONE" >> /tmp/zellij-tasks/doc.log'
# 后台任务 3:代码检查
zellij action -s "$SESSION" run -n "检查" -- \
bash -c 'cargo clippy 2>&1 | tee /tmp/zellij-tasks/clippy.log; \
echo "CLIPPY_DONE" >> /tmp/zellij-tasks/clippy.log'
echo "所有后台任务已启动,会话名: $SESSION"
echo "查看进度: zellij attach $SESSION"
echo "查看日志: cat $LOG_DIR/*.log"
四、程序化控制
控制面概览
Zellij 的程序化控制可以分为四个维度:
- 查询:获取会话、面板、标签页的当前状态。对应命令:
list-panes、list-tabs、current-tab-info、dump-screen - 变更:创建、关闭、修改面板和标签页。对应命令:
new-pane、close-pane、send-keys、run、edit - 观察:持续监听面板事件和输出。对应命令:
subscribe、watch - 阻塞:等待某个条件满足后继续。对应命令:
--blocking、--block-until-exit-success、--block-until-exit-failure
控制循环模式
大多数 Zellij 脚本遵循相同的控制循环模式:
创建会话 → 打开面板 → 发送命令 → 观察输出 → 反应 → 重复
具体来说:
- 创建会话:
zellij -s my-session -d创建一个分离会话 - 打开面板:
zellij action -s my-session run -- cmd在会话中运行命令 - 发送命令:
zellij action send-keys --pane-id N "input" Enter - 观察输出:通过
dump-screen或subscribe获取面板内容 - 反应:根据输出内容执行不同的操作分支
等待输出条件
在脚本中等待面板输出满足特定条件有四种主要方法:
方法一:阻塞面板(最可靠)
# 阻塞等待命令完成
zellij action run --blocking -- cargo build
echo "构建完成"
方法二:轮询 dump-screen(最灵活)
# 轮询等待特定字符串出现
wait_for_output() {
local pane_id=$1
local pattern=$2
local max_wait=$3
local elapsed=0
while [ $elapsed -lt $max_wait ]; do
OUTPUT=$(zellij action dump-screen)
if echo "$OUTPUT" | grep -q "$pattern"; then
return 0
fi
sleep 1
elapsed=$((elapsed + 1))
done
return 1
}
wait_for_output 1 "BUILD SUCCESSFUL" 120
方法三:轮询退出状态(最简单)
# 等待面板进程退出
wait_for_exit() {
local pane_id=$1
while zellij action list-panes | grep -q "id: $pane_id"; do
sleep 1
done
}
方法四:subscribe 流式观察(最实时)
# 流式监控面板输出
zellij subscribe --pane-id 1 terminal_1 | \
jq -r '.data' | \
while IFS= read -r line; do
if echo "$line" | grep -q "DONE"; then
echo "任务完成"
break
fi
done
快照与流式观察的选择
dump-screen(快照)和 subscribe(流式)各有适用场景:
| 方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
dump-screen | 简单直观,获取完整屏幕内容 | 需要轮询,可能错过短暂输出 | 一次性检查、简单条件等待 |
subscribe | 实时获取所有输出,不会遗漏 | 输出量大,需要持续处理 | 流式日志分析、实时事件响应 |
结构化输出参考
以下命令支持 JSON 结构化输出,方便脚本解析:
zellij action list-panes:输出所有面板的 ID、名称、尺寸等信息zellij action list-tabs:输出所有标签页的索引、名称、面板列表zellij action current-tab-info:输出当前标签页的详细信息zellij subscribe:输出面板事件的 JSON 流zellij action dump-screen:输出面板的纯文本屏幕内容zellij list-sessions:列出所有会话及其状态
并发与顺序
默认情况下,多个 zellij action 命令可以并发执行。例如同时启动多个面板运行不同任务:
# 并发启动多个任务
zellij action run -n "构建" -- cargo build &
zellij action run -n "测试" -- cargo test &
zellij action run -n "检查" -- cargo clippy &
wait
echo "所有任务已启动"
如果需要顺序执行(前一个完成后再执行下一个),使用 --blocking 选项:
# 顺序执行:构建 → 测试 → 部署
zellij action run --blocking -- cargo build || exit 1
zellij action run --blocking -- cargo test || exit 1
zellij action run --blocking -- ./deploy.sh || exit 1
echo "全部完成"
通过灵活组合并发和顺序执行,你可以构建出从简单到复杂的各种自动化工作流。Zellij 的 CLI 操作 + subscribe/watch 机制,使得终端多路复用器不再只是手动操作的工具,而成为了可编程的自动化平台。