跳转到内容

终端与 Shell 会话

NetShuttle 不把终端绑定到单一界面。共享层使用 ShellSession 与 ShellSessionManager 管理远程 PTY,展示层根据平台选择外部终端或应用内终端。

creating → running ←→ detached → closing → closed
↓
lost

关闭终端窗口默认只执行 detach,远程 Shell 继续运行。只有用户明确结束会话、SSH 连接销毁或连接断开时,才会 destroy 对应 Shell。

一个 SSH 连接可以创建多个独立 Shell。ShellID 与 ConnectionID 分离,Bridge 和终端展示路由只依赖具体 ShellID。

macOS 菜单栏中的「打开终端」会优先附加该连接最近 detached 的 Shell;没有可恢复会话时再创建新 Shell。

执行链如下:

  1. NetShuttle 启动当前终端的 NetShuttle.app/Contents/MacOS/NetShuttle tty <sessionID>。
  2. CLI 连接本地 Unix Domain Socket,并发送包含尺寸、TERM 和 LANG 的 HELLO。
  3. TTY Bridge 附加已有 Shell,或通过 SSH 引擎创建新的 PTY Channel。
  4. READY 返回 shellID 后,CLI 进入原始终端模式并开始双向转发。
  5. 终端尺寸变化通过 SIGWINCH 转换为 RESIZE;关闭终端只 detach。
终端启动策略顺序
Terminal.appcommandFile → appleScriptDoScript
iTerm2appleScriptWriteText → commandFile
GhosttyappleScriptSurfaceCommand → commandFile

应用还支持选择一个未知 .app。终端品牌与启动策略由内置 TerminalProfiles.json 描述,Swift 代码不包含品牌枚举。

终端 App 启动成功不等于 Shell 已可交互。每个已提交策略最多等待 6 秒 READY;超时后按顺序回退。一个 Connection 同时只允许一条探测链,防止快速重复点击创建多个终端窗口。

移动端不启动 TTY Bridge,也不经过 Unix Socket。MobileTerminalLauncher 直接附加 ShellSessionManager 中的 Shell,MobileTerminalView 使用 SwiftTerm 展示:

  • 键盘输入写入 Shell。
  • 远端输出显示在终端。
  • 尺寸变化转发为 PTY resize。
  • 页面消失时 detach,点击「结束会话」时 destroy。

移动端首版只保证前台会话。应用进入后台后系统可能暂停连接,不能把移动端当作常驻后台隧道或终端服务器。