Terminal
Terminal Host 执行具有 stdin/stdout/stderr 访问权限的 Lua 脚本。
Entry 类型
| Kind | 描述 |
|---|---|
terminal.host |
Terminal 会话 host |
配置
- name: cli_host
kind: terminal.host
hide_logs: false
lifecycle:
auto_start: true
| 字段 | 类型 | 默认值 | 描述 |
|---|---|---|---|
hide_logs |
bool | false | 禁止向事件总线输出日志 |
Terminal 上下文
在 terminal host 上运行的脚本接收一个 terminal 上下文,包含:
- stdin - 标准输入读取器
- stdout - 标准输出写入器
- stderr - 标准错误写入器
- args - 命令行参数
可组合的终端
进程看到的 terminal 是一个端口,而不是设备。这使得终端的所有权可以组合。
运行在 terminal host 上的进程持有物理端口。它调用 tty.surface() 取得该端口的呈现租约并发布完整的帧——它拥有整个屏幕。
shell 进程通过 tty.viewport() 创建虚拟终端来托管其他进程。它经由 terminal spawn 选项把 viewport:grant() 传给子进程;子进程把该授权解析为一个普通的终端端口并照常运行,完全不知道自己并未连接到设备。shell 用 viewport:snapshot() 读取子进程的帧,把它们放置在自己布局中的任意位置,并用 viewport:send() 把输入转换到子进程的坐标系。
local view = assert(tty.viewport({width = 78, height = 20}))
local child = assert(process.with_options({terminal = assert(view:grant())})
:spawn_monitored("app:child", "app:workers"))
授权是一次性的:进程准入会消耗它,启动被拒绝会使其保持未解析状态,而无法附加终端的宿主会拒绝该 spawn,而不是丢弃此选项。
面向字节的程序通过 exec 加入同一模型。子进程分配一个 PTY 进程并调用 process:attach_terminal();该适配器负责 PTY 仿真、输入编码、尺寸调整和终止,并呈现到子进程所持有的任何端口上——无论是物理端口还是虚拟端口。
physical terminal -> shell surface -> viewport -> child process -> PTY proxy
Lua API
IO 模块 提供面向行的 terminal 操作:
local io = require("io")
io.write("Enter name: ")
local name = io.readline()
io.print("Hello, " .. name)
local args = io.args()
在 terminal 上下文之外调用函数会返回错误。
关于原始输入事件、样式化渲染、surface 和 viewport,参见 TTY。关于 PTY 进程和终端会话,参见 命令执行。
参见
- Terminal I/O — stdin/stdout/stderr 操作
- TTY — 输入事件、surface、画布和 viewport
- 命令执行 — PTY 进程和终端会话
- 终端 UI — 构建一个在 viewport 中托管子进程的 shell