☰
不止一条命令:Open Terminal交互式PTY终端与WebSocket实时I/O实战指南
2026/9/29 4:02:27 网站建设 项目流程

不止一条命令:Open Terminal交互式PTY终端与WebSocket实时I/O实战指南

【免费下载链接】open-terminalA computer you can curl ⚡项目地址: https://gitcode.com/gh_mirrors/ope/open-terminal

Open Terminal是一个"可以被 curl 的电脑"⚡:一个轻量级自托管终端服务,让 AI 智能体和自动化工具通过简单的 REST API 与 WebSocket 就能远程执行命令、管理文件。除了普通的"跑一条命令拿结果",它还内置了交互式 PTY 终端——你可以像真人一样与远程 shell 实时敲键盘、看彩色输出,本文带你从零上手这套 实时 I/O 玩法。

为什么需要交互式终端?

普通远程执行 API 只能"提交命令 → 等结果",遇到这些场景就束手无策了:

  • 🐍 进入 Python / Node.js 的REPL逐行调试
  • 🎛️ 运行top、vim、htop等TUI 程序,需要持续输入和动态刷新
  • 💬 给正在运行的程序喂输入(回答交互提示、发送 Ctrl-C 中断)

Open Terminal 从 v0.7.0 开始支持完整 PTY 终端会话,遵循 JupyterLab/Kubernetes 的经典模式:先创建会话,再通过 WebSocket 附着(attach),非阻塞 I/O 保证终端不会拖慢其他 API 请求。

一键启动:Docker 或裸机两种方式

# Docker 方式(推荐,沙箱隔离) docker run -d --name open-terminal --restart unless-stopped -p 8000:8000 \ -v open-terminal:/home/user -e OPEN_TERMINAL_API_KEY=your-secret-key \ ghcr.io/open-webui/open-terminal
# 裸机方式(pip 安装,命令直接跑在你的机器上) uvx open-terminal run --host 0.0.0.0 --port 8000 --api-key your-secret-key

启动后访问http://localhost:8000/docs即可查看完整的交互式 API 文档。详细说明见 README.md。

💡 不设置 API key 时会自动生成一个,用docker logs open-terminal就能拿到。

PTY 终端 API:四个接口玩明白

交互式终端由POST/GET/DELETE /api/terminals+WS /api/terminals/{id}四个端点构成,核心实现位于 main.py:

步骤接口作用
1️⃣ 创建POST /api/terminals分配一个真实 PTY,返回 8 位session_id
2️⃣ 查看GET /api/terminals列出当前用户/会话下的活跃终端
3️⃣ 附着WS /api/terminals/{id}双向实时收发,真正的"敲键盘看屏幕"
4️⃣ 销毁DELETE /api/terminals/{id}杀掉进程并清理资源

创建会话时,服务在 Linux 上调用pty.openpty()打开伪终端,默认窗口 24 行 × 80 列,并把TERM设为xterm-256color,所以ls --color的彩色输出、vim 的界面都能正常渲染(见 runner.py 中的PtyRunner实现)。

几个贴心的细节:

  • 🧵 非阻塞 I/O:PTY 读取跑在线程池里,16 个并发会话(可通过OPEN_TERMINAL_MAX_SESSIONS调整)互不阻塞
  • 🧹 自动清理:WebSocket 断开后会话自动回收;创建新会话前会先清掉已死亡的旧会话
  • 🪟 Windows 兼容:通过pywinpty(ConPTY)提供WinPtyRunner,Windows 上同样可用
  • 🔒 会话隔离:按X-User-Id/X-Session-Id头校验归属,其他用户看不到也连不上你的终端

WebSocket 实时 I/O:协议就三步

这是全文最精华的部分,完整实现见 ws_terminal。协议非常简洁:

第 1 步:首消息认证

连接建立后 10 秒内,客户端必须发送第一帧 JSON 文本:

{"type": "auth", "token": "<你的API_KEY>"}

认证失败会被以4001码直接关闭连接。

第 2 步:双向二进制 I/O

  • ⌨️ 客户端发送二进制帧→ 就是键盘输入(每个字节都直接写入 PTY 的 stdin)
  • 📺 服务端发送二进制帧→ PTY 的原始输出(stdout/stderr 已合并,和真实终端行为一致)

第 3 步:文本帧控制窗口大小

{"type": "resize", "cols": 120, "rows": 40}

发送一条文本 JSON 即可调整终端行列数,TUI 程序会立即按新尺寸重排界面。

用 Python 客户端websockets库的示意(理解流程即可,不必照搬):

import asyncio, json, websockets async def main(): async with websockets.connect("ws://localhost:8000/api/terminals/abc12345") as ws: await ws.send(json.dumps({"type": "auth", "token": "你的API_KEY"})) async def feed(): # 模拟键盘输入 while True: key = input("按键: ").encode() + b"\n" await ws.send(key) async def watch(): # 实时打印终端输出 async for out in ws: if isinstance(out, bytes): print(out.decode(errors="replace"), end="") await asyncio.gather(feed(), watch())

进阶:AI 也能"看着屏幕敲键盘"

v0.12.4 之后,Open WebUI 中的 AI 助手可以直接读取你连接的终端最近的输出,并向其发送文本——包括回答运行中程序弹出的交互提示。这两个端点设计得很有讲究:

  • GET /api/terminals/user/output—— 先"读屏",看看前台程序在等什么(见 main.py)
  • POST /api/terminals/user/input—— 再"敲键盘",发送真实换行即可提交输入

📌 最佳实践:先读再写。发送输入前先看一眼屏幕,避免前台已有程序在运行时误操作。

安全与配置要点

  • 🔑API Key 必配:HTTP 与 WebSocket 认证都使用常量时间比较(hmac.compare_digest),防止时序攻击;key 建议放在config.toml里,避免出现在ps输出中
  • ⚠️裸机模式风险:命令直接以你的权限运行,生产环境强烈建议用 Docker 沙箱
  • ⚠️多用户模式(OPEN_TERMINAL_MULTI_USER=true)只隔离工作区,不构成安全边界,仅适合全员互信的小团队;需要真正隔离请用每用户独立实例
  • 🚪 不需要终端功能时,可设OPEN_TERMINAL_ENABLE_TERMINAL=false直接卸载全部终端路由与 WebSocket 端点

配置文件优先级:CLI 参数 > 环境变量 > 用户配置(~/.config/open-terminal/config.toml)> 系统配置(/etc/open-terminal/config.toml),详见 config.py。

小结:把"远程电脑"玩出花

能力关键 API一句话总结
后台跑命令POST /execute适合脚本化、轮询取结果
交互式终端POST /api/terminals+WS真实 PTY,REPL/TUI/彩色输出全支持
AI 接管终端/api/terminals/user/output+/input让模型读屏 + 敲键盘,回答交互提示

Open Terminal 把"能跑命令"升级成了"像人一样用终端":一个 PTY 会话 + 一条 WebSocket,就能在浏览器或 AI 聊天框里获得完整的交互 shell 体验。接下来不妨试着在终端里跑一个python -i或top,亲手感受下实时 I/O 的丝滑吧 🚀


核心源码导航:终端会话管理 open_terminal/main.py、PTY 进程运行器 open_terminal/utils/runner.py、进程日志 open_terminal/utils/log.py、完整更新历史 CHANGELOG.md

【免费下载链接】open-terminalA computer you can curl ⚡项目地址: https://gitcode.com/gh_mirrors/ope/open-terminal

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询