ctty Logo

# 🚀 ctty - 连接管理器 [English](README.md) | [中文](README_CN.md) [![Go](https://img.shields.io/badge/Go-1.23+-00ADD8?style=for-the-badge&logo=go)](https://golang.org/) [![Release](https://img.shields.io/github/v/release/zsuroy/ctty?style=for-the-badge)](https://github.com/zsuroy/ctty/releases) [![License](https://img.shields.io/github/license/zsuroy/ctty?style=for-the-badge)](LICENSE) [![Platform](https://img.shields.io/badge/platform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey?style=for-the-badge)](https://github.com/zsuroy/ctty/releases) > **一个轻量级的一体化终端连接管理器 —— SSH、串口、Telnet、SFTP、FTP、WebDAV 尽在一个 TUI** 🔥 > **一个轻量全能的终端连接管理器 —— 在单个 TUI 中融合 SSH、串口、Telnet、SFTP、FTP、WebDAV 和 S3 对象存储** 🔥 ctty 是一个快速、原生的终端工具,用于管理你的所有连接 —— SSH 主机、串口设备、Telnet 端点、SFTP 文件传输、FTP 站点、WebDAV 云盘以及 S3 对象存储 —— 无需 Electron 的开销。使用 Go 编写,拥有直观的 TUI 界面,将 Tabby 等图形化连接管理器的便利性带到终端中,零臃肿。 **为什么选择 ctty?** - **嫌 Tabby 太重?** ctty 是单个约 5MB 的二进制文件,没有 Electron,没有浏览器引擎 —— 纯 Go - **需要一个工具同时搞定串口 + Telnet + SFTP + FTP + WebDAV + S3 + SSH?** 大多数终端只做 SSH;ctty 一个二进制全搞定 —— 串口/Telnet/FTP/WebDAV/S3/SFTP 原生内置,SSH 复用系统 OpenSSH - **想留在终端里?** 不用在多个应用间切换 —— 一切都由键盘驱动

Demo ctty Terminal
🖱️ 点击图片查看完整大小

## ✨ 功能特性 ### 🚀 **核心能力** - **🎨 精致优雅的 TUI 终端界面** - 极客风全键盘交互终端 UI,零垂直跳动,平滑稳定 - **⚡ 快速连接与健康速览** - 回车一键直连,或按 `v`(或 `P`)呼出**轻量健康速览卡片**,无需进入完整 Shell 即可后台非交互采集并以彩色进度条查看 Uptime、CPU 负载、内存与根磁盘占用 - **📦 空格多选与批量操作** - 按 `Space` 切换勾选(带 `[ ]` / `[✓]` 复选框及光标自动下移),`Ctrl+A` 一键全选/反选;支持针对已选主机的批量连通性探测(`p`)、批量复制连接命令(`y`)、批量并发执行远程代码片段并聚合查看结果(`x`) - **🔄 全协议平滑切换与直达** - 任意页面按 `[` / `]` 循环切换协议标签页,或直接按 `t`(串口)、`T`(Telnet)、`F`(FTP)、`W`(WebDAV)、`O`(S3 对象存储)、`b`(本地文件浏览器)随时跳转对应模块,告别反复退回主页 - **🏷️ Tag 颜色标记与抽屉式快滤** - 标签自动彩色哈希高亮区分(如 `#prod` 红色、`#dev` 绿色、`#db` 紫色);按 `w` 呼出居中标签抽屉,清晰展示标签主机统计数量,按数字键 `1`-`9` 即可一键选定过滤,按 `c` 随时清除;特殊标签 `hidden` 从列表中隐藏但保持可连接 - **📝 极速系统编辑器直连** - 按 `E` 即可用系统编辑器(`$EDITOR`,如 vim、nano、notepad)直接编辑当前的 SSH 配置文件,退出编辑器后自动无缝热重载 - **📋 通用剪贴板** - 按 `y` 复制 SSH 连接命令,自动支持 OSC 52 终端转义序列,在远程 SSH 登录或 tmux 环境下也可同步写入宿主机系统剪贴板 - **🔄 端口转发** - 轻松设置本地、远程和动态(SOCKS)转发,带历史记录与复用 - **📝 轻松管理** - 无缝添加、编辑、移动和管理 SSH 配置;在搜索框打字后按 `a` 自动将输入内容带入添加主机表单 - **🔍 智能搜索** - 内置实时过滤和搜索,支持根据主机名、IP 地址及 `#标签` 即时匹配 - **📝 实时状态与阶梯时延** - 异步 ping 检查与多阶梯网络时延高亮指示(🟢 <100ms 优良、🟡 100-300ms 较慢、🔴 >300ms 离线/超时) - **🔌 串口连接** - 管理和连接串口设备(单片机、控制台、交换机、路由器),可配置波特率、数据位、校验、停止位;自动检测端口即时出现在列表中 - **📡 Telnet 连接** - 原生 RFC 854 telnet 客户端(无需系统 telnet):保存并管理实验室设备、控制台服务器和传统设备;一键探测可达性 - **📂 SFTP 文件传输** - 功能完整的 SFTP 浏览器(`o` 键):远程浏览、带进度和取消的上传/下载队列、传输完成终端响铃(`\a`)、搜索、新建/删除,以及无头 CLI 传输(`put`/`get`/`scp` + `sftp ls/mkdir/rm/rmdir/rename`) - **📁 FTP 站点管理** - 纯 FTP 支持(`F` 键),覆盖没有 SSH 的主机:带标签的站点清单、本地|远端双栏浏览器、双窗格新建/删除/重命名、单双栏切换、密码进加密保险库,以及 CLI 传输(`ftp ls/get/put/mkdir/rm/rmdir/rename`) - **🌐 WebDAV 站点管理** - WebDAV 支持(`W` 键),直连云存储与网盘(Nextcloud、ownCloud、NAS、Apache/Nginx WebDAV):带标签的站点清单、本地|远端双栏浏览器、目录递归传输、单双栏切换、密码进加密保险库,以及无头 CLI 传输(`webdav ls/get/put/mkdir/rm/rmdir/rename`) - **☁️ S3 对象存储管理** - 原生 S3 及兼容对象存储支持(`O` 键),覆盖 AWS S3、MinIO、Cloudflare R2、阿里云 OSS、Ceph 等:带标签的站点清单、本地|远端双栏浏览器、存储桶/前缀导航、双窗格新建/删除/重命名、带进度的上传/下载队列、单双栏切换、密钥安全加密保存,以及无头 CLI 操作(`s3 ls/get/put/mkdir/rm/rename`) - **🗂️ 本地文件浏览器** - 独立的本地文件管理器(`b` 键或 `ctty browse [路径]`):浏览、搜索、排序、新建/删除/重命名(含确认)、文件详情、默认应用打开、文件管理器定位 - **🔑 密码存储与免密自动登录** - 支持在本地 AES-256-GCM 加密保险库(`~/.config/ctty/credentials.json`,`0600` 权限)中安全保存密码,基于 OpenSSH 原生 `SSH_ASKPASS` 协议实现一键免密直连(零第三方依赖,完美兼容 macOS、Linux、Windows 和 Termux) - **🖥️ 分屏与极小窗口完美适配** - 所有表单与弹窗(添加/编辑主机、端口转发、帮助菜单、主机详情、速览卡片、批量执行)均采用焦点跟随的动态视口滚动,固定头部与底部导航;在 tmux/Zellij 分屏、VS Code/JetBrains 下方终端、i3/Sway 平铺窗口(即使只有 8~12 行)下均可丝滑操作,绝无高度拦截与内容裁切 - **🌐 多语言国际化与偏好设置** - 全界面支持中英双语,全平台自动检测系统语言(macOS / Windows / Linux / Termux),并内置交互式设置面板(按 `S` 键)实时切换与保存配置 ### 🛠️ **技术特性** - **🔒 安全** - 直接使用现有的 `~/.ssh/config` 文件(密码凭据独立存储,绝不污染标准 SSH 配置) - **📁 自定义配置** - 通过 `-c` 标志使用任意 SSH 配置文件 - **🤖 Agent Skill / 非交互 CLI** - 内置 agent skill(Cursor / Claude Code / Codex);不开 TUI 也能通过命令行完成全部操作,支持 JSON 输出,方便脚本和 AI 集成 - **📦 多工具主机导入** - 支持从 Tabby、Termius、FinalShell 或通用 JSON 一键迁移配置:`ctty import --from ` - **💾 配置备份与跨机迁移** - 支持全量配置与密码凭据归档与恢复(`ctty backup` / `ctty restore`,支持 AES-256-GCM 加密),或通过 `ctty export` 导出连接配置 - **📂 SSH Include 支持** - 完整支持 SSH Include 指令,跨多文件组织配置 - **⚙️ SSH 选项** - 通过直观的表单添加任意 SSH 配置选项 - **🔄 自动转换** - 命令行和配置格式之间无缝转换 - **🔄 自动备份** - 修改前自动备份配置 - **✅ 验证** - 内置验证防止配置错误 - **🔗 ProxyJump/ProxyCommand** - 通过跳板机安全连接隧道 - **⌨️ 键盘快捷键** - Vim 风格快捷键导航与全局 `Tab`/`Shift+Tab` 焦点循环切换 - **🌐 跨平台** - 支持 Linux、macOS(Intel 和 Apple Silicon)、Windows 及 Android(Termux) - **⚡ 轻量** - 单二进制,无依赖,零配置 ## 🚀 快速开始 ### Agent Skill 给 Cursor、Claude Code、Codex 等 agent 装一份 **怎么用 ctty** 的技能(搜主机、跑远程命令、列出串口/Telnet 设备)。技能安装之后可以直接让 Agent: "帮我安装 ctty" ```bash # 只列出仓库里的 skill,不安装 npx skills add zsuroy/ctty --list # 装到当前项目(写入 .agents/skills/) npx skills add zsuroy/ctty -y # 装到本机全局,所有项目都能用(推荐) npx skills add zsuroy/ctty -g -y ``` `-y` 跳过确认。`-g` 装到用户全局技能目录。不加 `-g` 则只装当前项目。 ```bash npx skills list # 查看已安装 npx skills remove ctty # 卸载 npx skills update ctty # 更新到最新 SKILL.md ``` 技能源文件在仓库的 [`skills/ctty/`](skills/ctty/)。 ### 安装 **Homebrew(macOS 推荐):** ```bash brew install zsuroy/ctty/ctty ``` **Unix/Linux/macOS(一行安装):** ```bash curl -sSL https://raw.githubusercontent.com/zsuroy/ctty/master/install/unix.sh | bash ``` **Termux(Android):** ```bash curl -sSL https://raw.githubusercontent.com/zsuroy/ctty/master/install/unix.sh | bash ``` 安装器自动检测 Termux(通过 `$PREFIX`/`$TERMUX_VERSION`),安装到 `$PREFIX/bin` 且不使用 `sudo`。在 Termux 上会自动选择 cgo 编译的 Android 包,其 DNS 走系统解析(纯 Go 包在 Private DNS 或 stub 解析的机器上会失败);没有 Android 产物的老版本回退到 Linux 包。 **Windows(PowerShell):** ```powershell irm https://raw.githubusercontent.com/zsuroy/ctty/master/install/windows.ps1 | iex ``` **其他方式:** *Linux/macOS:* ```bash # 下载指定版本 wget https://github.com/zsuroy/ctty/releases/latest/download/ctty_Linux_x86_64.tar.gz # 解压并安装 tar -xzf ctty_Linux_x86_64.tar.gz # 包内是单个 "ctty" 可执行文件 sudo mv ctty /usr/local/bin/ctty ``` *Windows:* ```powershell # 下载并解压 Invoke-WebRequest -Uri "https://github.com/zsuroy/ctty/releases/latest/download/ctty_Windows_x86_64.zip" -OutFile "ctty_Windows_x86_64.zip" Expand-Archive ctty_Windows_x86_64.zip -DestinationPath C:\tools\ # 将 C:\tools 添加到你的 PATH 环境变量 ``` **从源码构建(需要 Go 1.23+):** ```bash git clone https://github.com/zsuroy/ctty.git cd ctty go build -o ctty . sudo mv ctty /usr/local/bin/ ``` ## 📖 用法 ### 交互模式 运行 ctty(不带参数)进入 TUI 界面: ```bash ctty ``` **导航与主机操作:** - `↑/↓` 或 `j/k` - 浏览主机列表 - `Enter` - 连接到选中的主机 - `v` 或 `P` - **健康速览**主机实时运行状态(Uptime、CPU 负载、内存进度条、根磁盘空间) - `Space` - **多选**切换勾选(带 `[ ]` / `[✓]` 标记,光标自动下移一行) - `Ctrl+A` - 全选 / 全不选当前可视主机 - `Esc` - 清空已选主机(多选激活时)或退出当前模式 - `y` - 复制 SSH 连接命令到系统剪贴板(多选时按换行批量复制所有已选主机命令) - `x` - 远程命令代码片段执行(多选时并发批量执行,弹窗聚合展示各主机执行结果与耗时) - `p` - 探测主机网络连通性与时延(多选时仅探测已选中的主机) - `w` - 打开**标签抽屉过滤弹窗**(数字键 `1`-`9` 或 `Enter` 快速选定,`c` 清除) - `c` - 清除当前标签过滤 - `E` - 用系统编辑器(vim/nano/notepad)直接编辑当前 SSH 配置文件(退出自动热重载) - `[` / `]` - 切换至上一个 / 下一个协议 Tab(SSH ⇄ 串口 ⇄ Telnet ⇄ FTP ⇄ WebDAV ⇄ S3 ⇄ 本地浏览器) - `g` / `Home` - 快速跳至首行 - `G` / `End` - 快速跳至末行 - `1`-`9` - 快速跳至指定行号 - `a` - 添加主机配置(搜索框有输入时自动预填主机名) - `e` - 编辑选中的主机配置 - `d` - 删除选中的主机 - `m` - 移动主机到其他配置文件(需要 SSH Include 指令) - `i` - 查看主机详细配置信息 - `f` - 配置端口转发 - `t` - 打开串口设备管理器 - `T` - 打开 Telnet 设备管理器 - `o` - 打开选中主机的 SFTP 文件浏览器 - `F` - 打开 FTP 站点管理器 - `W` - 打开 WebDAV 站点管理器 - `O` - 打开 S3 对象存储管理器 - `b` - 打开本地文件浏览器 - `S` - 打开系统设置与偏好配置(语言、自动更新、ESC 行为) - `U` - 打开自更新弹窗(有可用更新时) - `H` - 切换隐藏主机的显示/隐藏状态 - `h` - 打开帮助菜单 - `q` - 退出应用程序 - `/` - 搜索/过滤主机 **实时状态指示:** - 🟢 **在线** - 低时延(<100ms) - 🟡 **较慢 / 连接中** - 中等时延(100-300ms)或正在探测连接 - 🔴 **离线 / 超时** - 主机不可达、超时或高时延(>300ms) - ⚫ **未知** - 连通性状态尚未确定 **排序与过滤:** - `s` - 循环切换 4 种排序模式(**主机名称** ➔ **主机地址** ➔ **标签** ➔ **上次登录**) - `n` - 按**主机名称**排序(字母顺序) - `r` - 按**最近连接**排序(上次登录时间) - `Tab` - 在搜索输入框与主机列表表格之间切换焦点 - 实时搜索 - 支持根据主机名、IP 地址及 `#标签` 进行即时过滤 交互式表单将引导你完成配置: - **主机名/IP** - 服务器地址 - **用户名** - SSH 用户 - **端口** - SSH 端口(默认:22) - **密钥文件** - 私钥路径 - **ProxyJump** - 跳板机连接隧道 - **ProxyCommand** - 跳板命令连接隧道 - **SSH 选项** - 额外的 SSH 选项,命令行格式(如 `-o Compression=yes -o ServerAliveInterval=60`) - **标签** - 逗号分隔的标签用于组织 ### 串口连接 按 `t` 从主 TUI 进入串口设备管理器。可用串口端口自动检测并立即列出 —— 无需手动设置即可快速访问。 **串口设备列表:** - 检测到的端口自动出现,使用默认设置(115200 8N1) - 保存的设备(带自定义名称和设置)排在顶部 - `Enter` - 连接到选中的串口设备 - `i` - 查看设备信息(名称、端口、波特率等) - `a` - 添加新的串口设备 - `d` - 删除已保存的串口设备 - `/` - 搜索/过滤设备(按名称或端口路径) - `Esc`/`q` - 返回 SSH 主机列表 **设备信息页:** - `e` 或 `Enter` - 编辑参数后连接(波特率/数据位/校验/停止位) - `Esc`/`i` - 返回设备列表 **添加串口设备:** - **名称** - 友好别名(如 `Switch-Console`) - **设备** - 端口路径(如 `/dev/cu.usbserial-1420`);用 `←/→` 从检测到的端口中选择 - **波特率** - 默认:115200 - **数据位** - 5、6、7 或 8(默认:8) - **校验** - `none`、`even` 或 `odd`(默认:`none`) - **停止位** - 1 或 2(默认:1) **连接前编辑参数:** - 波特率可直接输入,或用 `←/→` 在常用值间切换(9600/19200/38400/57600/115200/230400/460800/921600) - 按 `Enter` 用修改后的参数连接 **连接:** TUI 暂停并将终端直接桥接到串口。按 `Ctrl+]` 断开并返回 TUI。 也可以直接启动串口管理器: ```bash ctty serial # 跳过 SSH 主机列表,直接进入串口设备管理 ``` 串口设备配置存储在 `~/.config/ctty/serial.json`,与 `~/.ssh/config` 分离。 ### Telnet 连接 在主界面按 `T`(Shift+T)打开 Telnet 设备管理器 —— 适用于暴露 telnet 服务的实验室设备、控制台服务器和传统网络设备。 > ⚠️ **明文协议** — Telnet 以明文传输所有内容(包括密码)。设备支持时请优先使用 SSH。 **Telnet 设备列表:** - `Enter` - 连接选中的 Telnet 设备 - `i` - 查看设备详情(名称、主机、端口、用户、标签) - `a` - 添加新的 Telnet 设备 - `e` - 编辑选中的设备 - `d` - 删除已保存的 Telnet 设备 - `p` - 探测所有已保存主机的可达性(TCP 拨测,3 秒超时;🟢 在线 / 🔴 离线) - `/` - 搜索/过滤设备(按名称、主机或标签) - `Esc`/`q` - 返回 SSH 主机列表 **自动登录:** 通过 `a` / `e` 可为设备保存用户名/密码(密码存入加密保险库,与 SSH/FTP/WebDAV/S3 一致)。连接时,ctty 自动应答 `login:`/`Username:`/`user:`/`login as:` 与 `Password:`/`passwd:` 提示(用户名可选)。仅匹配行尾的真实提示词,每个提示最多应答一次且不会循环重试;未识别时回退手动输入。Telnet 为明文协议,此功能仅省输入,不增安全性。 **连接:** TUI 暂停并将终端直接桥接到 Telnet 会话。按 `Ctrl+]`(经典 telnet 转义符)断开并返回 TUI。客户端采用保守协商策略:接受 ECHO / SGA / BINARY,拒绝其他选项,窗口大小查询应答 80×24。 也可以不经管理器直接连接: ```bash ctty telnet # Telnet 设备管理器 TUI ctty telnet core-sw # 按名称连接已保存的设备 ctty telnet 192.168.1.1 # 直接连接(端口 23) ctty telnet 10.0.0.5:2001 # 指定端口直接连接 ``` 已保存的设备存储在 `~/.config/ctty/telnet.json`,与 SSH 配置分离。 ### SFTP 文件传输 选择 SSH 主机后,按 `o` 打开 SFTP 文件浏览器。SFTP 界面在终端中提供完整的文件传输体验: **SFTP 浏览器功能:** - 远程和本地文件浏览 - 带进度和取消功能的上传/下载 - 搜索功能(/ 键)用于远程和本地文件 - 双行帮助提示,更易阅读 - 清晰的 [LOCAL] 和 [REMOTE] 标签(无混淆的 emoji) - 友好的错误信息 **SFTP 导航:** - `↑/↓` 或 `j/k` - 浏览文件 - `→/l` 或 `Enter` - 进入目录 / 下载文件(远程) / 上传文件(本地) - `←/h` 或 `Backspace` - 返回上级目录 - `u` - 切换到本地文件浏览器以上传文件 - `d` - 删除选中的文件(仅远程) - `n` - 创建新目录(仅远程) - `r` - 刷新文件列表 - `/` - 搜索/过滤文件 - `Esc` - 取消当前操作 / 返回 SSH 会话 **上传文件:** 1. 按 `u` 切换到本地文件浏览器 2. 浏览到要上传的文件 3. 按 `Enter` 上传到当前远程目录 4. 在状态栏监控进度 5. 按 `Esc` 取消上传(返回远程文件列表) **下载文件:** 1. 浏览到要下载的文件 2. 按 `Enter` 下载到本地下载目录(`~/Downloads/ctty`) 3. 在状态栏监控进度 4. 按 `Esc` 取消下载(返回远程文件列表) **搜索文件:** - 按 `/` 进入搜索模式 - 输入以按文件名过滤(实时过滤) - 按 `Enter` 或 `Tab` 确认选择 - 按 `Esc` 取消搜索并恢复完整文件列表 **错误处理:** - 如果 SFTP 无法启动,会显示友好的错误信息:`❌ SFTP 错误:无法启动 SFTP 会话。` - 按 `Esc` 返回 SSH 会话 - SSH 连接保持活动状态,可进行其他操作 你也可以直接从命令行启动指定主机的 SFTP 文件浏览器: ```bash ctty sftp prod-server # 直接打开指定主机的 SFTP 文件浏览器 ``` **无头 SFTP 文件操作:** ```bash ctty sftp ls prod-server # 列出远端目录 ctty sftp ls prod-server /var/log --format json ctty sftp mkdir prod-server /tmp/newdir ctty sftp rm prod-server /tmp/file.txt ctty sftp rmdir prod-server /tmp/olddir ctty sftp rename prod-server /tmp/old.txt /tmp/new.txt # 传输仍在根级: ctty put prod-server ./app.tar.gz /srv/app.tar.gz ctty get prod-server /var/log/app.log ./app.log ``` ### FTP 文件传输 在主界面按 `F`(Shift+F)打开 FTP 站点管理器——适用于不支持 SSH/SFTP 的纯 FTP 主机(实验室 NAS、老旧文件服务器、设备上传口)。 > ⚠️ **明文协议** —— FTP 传输的所有内容(含密码)都不加密。只要服务器支持,优先用 SFTP。 **FTP 站点管理器:** - `Enter` - 打开选中站点的双栏浏览器 - `a`/`e` - 添加 / 编辑站点(名称、地址、端口、用户、密码、标签) - `d` - 删除选中站点(同时删除已保存的密码) - `i` - 查看站点详情(`e`/回车直接进入编辑) - `/` - 搜索/过滤站点 - `r` - 刷新列表 - `Esc` - 返回 站点保存在 `~/.config/ctty/ftp.json`(0600)。密码加密存放在共享凭据保险库(`~/.config/ctty/credentials.json`,FTP 条目以 `ftp:` 开头)——跟 SSH 密码是同一个 AES-256-GCM 保险库。 **FTP 浏览器(本地 | 远端双栏):** - `Tab`/`u` - 在本地和远端窗格间切换焦点 - `↑/↓` 或 `j/k` - 浏览文件 - `→/l` 或 `Enter` - 进入目录 / 下载文件(远端下载先确认) - `←/h` 或 `Backspace` - 返回上级目录 - `d` - 删除选中文件(需确认) - `n` - 新建目录 - `R` - 重命名选中的文件/目录 - `i` - 查看选中文件/目录的详情 - `v` - 切换单栏/双栏布局(持久保存) - `r` - 刷新当前目录 - `/` - 搜索/过滤文件 - `Esc` - 取消传输 / 返回 文件管理(`n`/`d`/`R`)在两个窗格都可用,按键与 SFTP 对齐。布局也可以在 `S` 设置 → FTP 浏览器布局里持久配置。窄终端(不足 80 列)始终使用单栏。 你也可以直接打开站点管理器或指定站点的浏览器: ```bash ctty ftp # FTP 站点管理器 TUI ctty ftp lab-nas # 直接打开指定站点的浏览器 ``` **无头 FTP 传输:** ```bash ctty ftp ls lab-nas # 列出远端目录 ctty ftp ls lab-nas /pub --format json # 机器可读列表 ctty ftp get lab-nas /pub/file.txt ./file.txt ctty ftp put lab-nas ./file.txt /pub/file.txt ctty ftp mkdir lab-nas /pub/newdir ctty ftp rm lab-nas /pub/file.txt ctty ftp rmdir lab-nas /pub/olddir ctty ftp rename lab-nas /pub/old.txt /pub/new.txt ``` 进度输出到 stderr;目录递归;密码复用加密保险库(`ftp:` 前缀)或匿名。 ### WebDAV 文件传输 在主界面按 `W`(Shift+W)或按 `[` / `]` 切换标签页打开 WebDAV 站点管理器——适用于 Nextcloud、ownCloud、NAS 服务器、Apache/Nginx WebDAV 或任意符合 RFC 4918 的云存储端点。 **WebDAV 站点管理器:** - `Enter` - 连接并打开文件浏览器 - `a` - 添加 WebDAV 站点(名称、URL、用户名、可选密码、跳过 TLS 验证开关、标签) - `e` - 编辑站点 - `d` - 删除站点(带居中确认弹窗) - `Space` / `Ctrl+A` - 多选站点批量删除 - `y` - 复制站点 URL - `i` - 查看站点详情 - `p` - 探测连通性 - `w` - 按标签过滤 - `/` - 搜索过滤站点 站点保存在 `~/.config/ctty/webdav.json`(0600)。密码加密存放在共享凭据保险库(`~/.config/ctty/credentials.json`,WebDAV 条目以 `webdav:` 开头)——使用安全的 AES-256-GCM 加密。 **WebDAV 浏览器(本地 | 远端双栏):** - `Tab` / `Shift+Tab` - 在本地与远端窗格之间切换焦点 - `Enter` / `l` / `→` - 进入目录或下载/上传选中的文件 - `h` / `←` / `Backspace` - 返回上一级父目录 - `v` - 切换单栏与双栏布局(设置自动持久化保存) - `i` - 查看文件/目录详情信息(大小、修改时间、路径) - `n` - 新建目录(在当前获焦窗格中) - `d` - 删除文件或目录(在当前获焦窗格中,含确认弹窗) - `R` - 重命名文件或目录(在当前获焦窗格中) - `r` - 刷新目录列表 - `/` - 搜索/过滤当前目录 - `Esc` - 取消正在进行的传输 / 返回 文件管理(`n`/`d`/`R`)在两个窗格都可用。窄终端(不足 80 列)自动切换为单栏显示。 你也可以直接打开站点管理器或指定站点的浏览器: ```bash ctty webdav # WebDAV 站点管理器 TUI ctty webdav nextcloud # 直接打开指定站点的浏览器 ``` **无头 WebDAV 传输:** ```bash ctty webdav ls nextcloud # 列出远端目录 ctty webdav ls nextcloud /Documents --format json # 机器可读列表 ctty webdav get nextcloud /Documents/report.pdf ./report.pdf ctty webdav put nextcloud ./backup/ /RemoteBackup/ ctty webdav mkdir nextcloud /Documents/Archive ctty webdav rm nextcloud /Documents/old.pdf ctty webdav rmdir nextcloud /Documents/TempDir # 递归删除远程目录 ctty webdav rename nextcloud /Documents/a.pdf /Documents/b.pdf ``` 进度输出到 stderr;目录支持自动递归;密码安全读取加密保险库。 ### S3 对象存储 在主界面按 `O`(Shift+O)或按 `[` / `]` 切换标签页打开 S3 对象存储管理器——连接 AWS S3、MinIO、Cloudflare R2、阿里云 OSS、Ceph 等任意兼容 S3 协议的对象存储端点。 **S3 站点管理器:** - `Enter` - 连接并打开对象存储浏览器(浏览存储桶列表或指定存储桶内的对象) - `a` - 添加 S3 站点(名称、Endpoint 地址、存储桶名称、区域 Region、Access Key、Secret Key、SSL 开关、路径样式 PathStyle、跳过 TLS 验证、标签) - `e` - 编辑站点 - `d` - 删除站点(带居中确认弹窗) - `Space` / `Ctrl+A` - 多选站点批量删除 - `y` - 复制站点 Endpoint - `i` - 查看站点详情 - `p` - 探测连通性 - `w` - 按标签过滤 - `/` - 搜索过滤站点 - `Esc` - 返回 站点保存在 `~/.config/ctty/s3.json`(0600)。Secret Key 加密存放在共享凭据保险库(`~/.config/ctty/credentials.json`,S3 条目以 `s3:` 开头)——使用安全的 AES-256-GCM 加密。 **S3 浏览器(本地 | 远端双栏):** - `Tab` / `Shift+Tab` - 在本地与远端窗格之间切换焦点 - `Enter` / `l` / `→` - 进入存储桶/目录或下载/上传选中的文件 - `h` / `←` / `Backspace` - 返回上一级父目录或存储桶列表 - `v` - 切换单栏与双栏布局(设置自动持久化保存) - `i` - 查看文件/目录/对象详情信息(大小、修改时间、ETag、路径) - `n` / `a` - 新建存储桶或目录(在当前获焦窗格中) - `d` - 删除文件或目录前缀(在当前获焦窗格中,含确认弹窗) - `R` - 重命名文件或目录前缀(在当前获焦窗格中) - `r` - 刷新对象列表 - `/` - 搜索/过滤当前目录 - `Esc` - 取消正在进行的传输 / 返回 文件管理(`n`/`d`/`R`)在两个窗格都可用。窄终端(不足 80 列)自动切换为单栏显示。 你也可以直接打开站点管理器或指定站点的浏览器: ```bash ctty s3 # S3 站点管理器 TUI ctty s3 minio # 直接打开指定站点的浏览器 ``` **无头 S3 操作:** ```bash ctty s3 list # 列出已配置的 S3 站点 ctty s3 list --format json # 机器可读站点列表 ctty s3 ls minio # 列出存储桶或根目录 ctty s3 ls minio my-bucket/photos --format json # 机器可读对象列表 ctty s3 get minio my-bucket/docs/report.pdf ./report.pdf # 下载单文件或递归前缀 ctty s3 put minio ./backup/ my-bucket/backup/ # 上传单文件或递归目录 ctty s3 mkdir minio my-bucket/Archive # 创建存储桶或目录标记 ctty s3 rm minio my-bucket/old.pdf # 删除对象 ctty s3 rm minio my-bucket/TempDir -r # 递归删除前缀 ctty s3 rename minio my-bucket/old.txt new.txt # 重命名 / 移动对象 ctty s3 mv minio my-bucket/olddir my-bucket/newdir # 重命名 / 移动前缀 ``` 进度输出到 stderr;目录支持自动递归;Secret Key 安全读取加密保险库。 ### 端口转发 ctty 提供直观的界面来设置 SSH 端口转发。在选中主机时按 `f` 打开端口转发设置: **转发类型:** - **本地(-L)** - 通过 SSH 连接将本地端口转发到远程主机/端口 - 示例:通过本地端口 `15432` 访问远程数据库 `localhost:5432` - 用法:`ssh -L 15432:localhost:5432 server` → 数据库可在 `localhost:15432` 访问 - **远程(-R)** - 将远程端口转发回本地主机/端口 - 示例:在远程主机的 `8080` 端口暴露本地 Web 服务器 - 用法:`ssh -R 8080:localhost:3000 server` → 本地应用可从远程主机的 8080 端口访问 - ⚠️ **外部访问要求:** - **SSH 服务器配置**:在 `/etc/ssh/sshd_config` 中添加 `GatewayPorts yes` 并重启 SSH 服务 - **防火墙**:在服务器防火墙中开放远程端口(`ufw allow 8080` 或等效命令) - **端口可用性**:确保远程端口未被占用 - **绑定地址**:外部访问用 `0.0.0.0`,仅本地用 `127.0.0.1` - **动态(-D)** - 创建 SOCKS 代理用于安全浏览 - 示例:通过 SSH 连接路由 Web 流量 - 用法:`ssh -D 1080 server` → 配置浏览器使用 `localhost:1080` 作为 SOCKS 代理 - ⚠️ **配置要求:** - **浏览器设置**:在浏览器设置中配置 SOCKS v5 代理 - **DNS**:启用 "Proxy DNS when using SOCKS v5" 以获得完整隐私 - **应用程序**:只有支持 SOCKS 的应用程序会使用代理 - **绑定地址**:出于安全考虑使用 `127.0.0.1`(仅本地访问) **端口转发界面:** - 用 ←/→ 箭头键选择转发类型 - 通过引导式表单配置端口和地址 - 可选绑定地址配置(默认 127.0.0.1) - 实时验证端口号和地址 - **端口转发历史** - 保存常用配置以便快速复用 - 使用配置好的转发选项自动连接 **端口转发故障排除:** *远程转发问题:* ```bash # 错误:"remote port forwarding failed for listen port X" # 解决方案: 1. 检查端口是否已占用:ssh server "netstat -tln | grep :X" 2. 使用其他可用端口 3. 在 SSH 配置中启用 GatewayPorts 以允许外部访问 ``` *远程转发的 SSH 服务器配置:* ```bash # 编辑服务器上的 SSH 守护进程配置: sudo nano /etc/ssh/sshd_config # 添加或取消注释: GatewayPorts yes # 重启 SSH 服务: sudo systemctl restart sshd # Ubuntu/Debian/CentOS 7+ # 或 sudo service ssh restart # 旧系统 ``` *防火墙配置:* ```bash # Ubuntu/Debian (UFW): sudo ufw allow [端口号] # CentOS/RHEL/Rocky (firewalld): sudo firewall-cmd --add-port=[端口号]/tcp --permanent sudo firewall-cmd --reload # 检查端口是否可访问: telnet [服务器IP] [端口号] ``` *动态转发(SOCKS)浏览器设置:* ``` Firefox: about:preferences → 网络设置 - 手动代理配置 - SOCKS 主机: localhost, 端口: [你的端口] - SOCKS v5: ✓ - 使用 SOCKS v5 时代理 DNS: ✓ Chrome: 启动时指定代理 chrome --proxy-server="socks5://localhost:[你的端口]" ``` ### 远程命令执行 按 `x` 选择主机后打开远程命令执行界面,可以在远程主机上执行命令,无需打开交互式 SSH 会话。 **功能特性:** - 内置常用命令代码片段:`docker ps`、`df -h`、`free -m`、`uptime`、`top`、`last`、`ps`、`du` - 使用 `n` 键添加自定义代码片段(保存到 `~/.config/ctty/snippets.json`,权限 `0600`) - 使用 `d` 键删除自定义代码片段 - 用户自定义的代码片段在列表中用 ★ 标记 - `Tab` 键可将选中的代码片段填入输入框 - `↑/↓` 键浏览代码片段 - `Enter` 键执行命令 - 支持已保存密码的 SSH 自动登录 - 首次连接自动接受主机密钥(无需交互式输入 `yes/no`) **命令执行界面导航:** - `↑/↓` 或 `j/k` - 浏览命令代码片段 - `Tab` - 将选中的代码片段填入输入框 - `Enter` - 执行命令 - `n` - 添加新的自定义代码片段 - `d` - 删除选中的自定义代码片段 - `Esc` - 返回主机列表 ### 命令行用法 ctty 同时提供命令行操作和交互式 TUI 界面: ```bash # 启动交互式 TUI 模式浏览和连接主机 ctty # 直接连接到指定主机(带历史记录) ctty my-server # 在远程主机上执行命令 ctty my-server uptime # 执行带参数的命令 ctty my-server ls -la /var/log # 强制 TTY 分配(用于交互式命令) ctty -t my-server sudo systemctl restart nginx # 使用自定义 SSH 配置文件启动 TUI ctty -c /path/to/custom/ssh_config # 使用自定义 SSH 配置文件直接连接 ctty my-server -c /path/to/custom/ssh_config # 使用交互式表单添加主机 ctty add # 添加主机并预填主机名 ctty add hostname # 使用自定义 SSH 配置文件添加主机 ctty add hostname -c /path/to/custom/ssh_config # 编辑现有主机配置 ctty edit my-server # 使用自定义 SSH 配置文件编辑主机 ctty edit my-server -c /path/to/custom/ssh_config # 移动主机到其他 SSH 配置文件(需要 Include 指令) ctty move my-server # 使用自定义 SSH 配置文件移动主机(需要 Include 指令) ctty move my-server -c /path/to/custom/ssh_config # 搜索主机(交互式过滤或关键字/标签查询) ctty search ctty search prod ctty search "#web" # 测试主机连通性与网络延迟 ctty ping prod-server ctty ping web1 web2 --json ctty ping --tags prod --all # 探测并检查主机实时运行指标(运行时间、CPU 负载、内存 %、磁盘 %) ctty peek prod-server ctty peek web1 web2 --json ctty peek --tags prod --concurrency 4 # 直接打开指定主机的 SFTP 文件浏览器 ctty sftp prod-server # 打开 FTP 站点管理器,或直接打开指定站点的浏览器 ctty ftp ctty ftp lab-nas # FTP 无头传输(无需 TUI,目录递归,进度在 stderr) ctty ftp ls lab-nas /pub --format json ctty ftp get lab-nas /pub/file.txt ./file.txt ctty ftp put lab-nas ./file.txt /pub/file.txt ctty ftp mkdir lab-nas /pub/newdir ctty ftp rm lab-nas /pub/file.txt ctty ftp rmdir lab-nas /pub/olddir ctty ftp rename lab-nas /pub/old.txt /pub/new.txt # 打开 WebDAV 站点管理器,或直接打开指定站点的浏览器 ctty webdav ctty webdav nextcloud # WebDAV 无头传输(无需 TUI,目录递归,进度在 stderr) ctty webdav ls nextcloud /Documents --format json ctty webdav get nextcloud /Documents/report.pdf ./report.pdf ctty webdav put nextcloud ./backup/ /RemoteBackup/ ctty webdav mkdir nextcloud /Documents/Archive ctty webdav rm nextcloud /Documents/old.pdf ctty webdav rmdir nextcloud /Documents/TempDir ctty webdav rename nextcloud /Documents/a.pdf /Documents/b.pdf # 打开 S3 站点管理器,或直接打开指定站点的浏览器 ctty s3 ctty s3 minio # S3 无头操作(无需 TUI,进度在 stderr) ctty s3 list --format json ctty s3 ls minio my-bucket/docs --format json ctty s3 get minio my-bucket/docs/report.pdf ./report.pdf ctty s3 put minio ./backup/ my-bucket/backup/ ctty s3 mkdir minio my-bucket/Archive ctty s3 rm minio my-bucket/old.pdf ctty s3 rm minio my-bucket/TempDir -r ctty s3 rename minio my-bucket/old.txt new.txt ctty s3 mv minio my-bucket/olddir my-bucket/newdir # 浏览本地文件系统(搜索、新建/删除/重命名、文件详情) ctty browse ctty browse ~/Downloads # 直接打开串口设备管理器 ctty serial # 不开表单,用参数直接新增/编辑主机 ctty add --name web-server --hostname 10.0.1.10 --user root --tags prod ctty edit --name web-server --port 2222 # 用 SFTP 直接传输文件(无需打开 TUI) ctty put web-server ./app.tar.gz /srv/www/app.tar.gz ctty get web-server /var/log/app.log ./app.log ctty scp web-server:/etc/ctty.conf ./ctty.conf # 一次在多台主机上执行同一条命令 ctty exec --tags prod --list-hosts ctty exec --tags prod -- uptime ctty exec --hosts web-01,db-01 -- df -h # 用 JSON 查询已保存的串口 / Telnet 设备(方便脚本对接) ctty serial list --format json ctty telnet search core --format json # 备份配置与凭据(支持可选 AES-256-GCM 密码加密) ctty backup -o my-backup.tar.gz ctty backup -p "passphrase" -o backup.ctty # 从备份归档中恢复配置文件 ctty restore backup.tar.gz --dry-run ctty restore backup.ctty -p "passphrase" --overwrite # 导出连接配置为 JSON 或 OpenSSH 格式 ctty export --format json ctty export --format ssh --tags prod # 从 Tabby、Termius、FinalShell 或通用 JSON 导入主机 ctty import tabby --dry-run ctty import termius -f ./termius-export.json ctty import finalshell -f ~/.finalshell/conn ctty import json -f ./hosts.json # 指定界面语言(auto, zh, en) ctty --lang zh ctty search prod --lang en # 输出机器可读的信息(JSON)用于脚本 ctty info prod-server ctty info prod-server --pretty # 使用自定义 SSH 配置文件 ctty -c /path/to/custom/ssh_config info prod-server # 管道到 jq ctty info prod-server | jq -r '.result.target.hostname' ctty info prod-server | jq -r '.result.target.user' # 显示版本信息 ctty --version # 禁用自动更新检查(适用于离线机器) ctty --no-update-check # 自更新:检查新版本(加 --yes 直接下载并安装) ctty update ctty update --yes # 从 Tabby 导入 SSH 主机(写入 ~/.ssh/config.d/tabby.conf) ctty import --from tabby ctty import tabby --dry-run ctty import tabby -f /path/to/tabby/config.yaml # 显示帮助和可用命令 ctty --help ``` ### 主机信息(JSON) `ctty info ` 输出单个 JSON 对象到 stdout,可以用 `jq` 脚本化处理。 ```bash # 提取字段 ctty info prod-server | jq -r '.result.target.hostname' ctty info prod-server | jq -r '.result.target.port' # 检查不存在的主机(退出码 2) ctty info does-not-exist | jq -r '.error.code' ``` ### Shell 补全 ctty 支持主机名的 shell 补全,方便不用输入全名即可连接: ```bash ctty # 列出所有可用主机 ctty pro # 补全以 "pro" 开头的主机(如 prod-server) ``` **设置说明:** **Bash:** ```bash # 当前会话启用 source <(ctty completion bash) # 永久启用(添加到 ~/.bashrc) echo 'source <(ctty completion bash)' >> ~/.bashrc ``` **Zsh:** ```bash # 当前会话启用 source <(ctty completion zsh) # 永久启用(添加到 ~/.zshrc) echo 'source <(ctty completion zsh)' >> ~/.zshrc ``` **Fish:** ```bash # 当前会话启用 ctty completion fish | source # 永久启用 ctty completion fish > ~/.config/fish/completions/ctty.fish ``` **PowerShell:** ```powershell # 当前会话启用 ctty completion powershell | Out-String | Invoke-Expression # 永久启用(添加到你的 PowerShell 配置文件) Add-Content $PROFILE 'ctty completion powershell | Out-String | Invoke-Expression' ``` ### 直接连接主机 ctty 支持通过命令行直接连接主机,方便集成到现有工作流: ```bash # 直接连接到任意已配置的主机 ctty production-server ctty db-staging ctty web-01 # 所有直接连接都会记录在历史中 # 使用 TUI 查看最近连接的主机 ``` **直接连接的特点:** - **即时连接** - 无需 TUI 导航 - **历史记录** - 所有连接都会记录时间戳 - **错误处理** - 主机不存在或配置问题时显示清晰消息 - **配置文件支持** - 使用 `-c` 标志支持自定义配置文件 ### 远程命令执行 无需打开交互式 shell 即可在远程主机上执行命令: ```bash # 执行单个命令 ctty prod-server uptime # 执行带参数的命令 ctty prod-server ls -la /var/log # 检查磁盘使用 ctty prod-server df -h # 查看日志(管道到本地命令) ctty prod-server 'cat /var/log/nginx/access.log' | grep 404 # 强制 TTY 分配(用于交互式命令如 sudo、vim 等) ctty -t prod-server sudo systemctl restart nginx ``` **特点:** - **退出码传递** - 远程命令的退出码会传递回来 - **TTY 支持** - 使用 `-t` 标志用于需要终端交互的命令 - **管道友好** - 输出可管道到本地命令处理 - **历史记录** - 命令执行会记录在连接历史中 ### 备份配置 ctty 在修改前自动创建 SSH 配置文件备份,确保配置安全。 **备份位置:** - **Unix/Linux/macOS**: `~/.config/ctty/backups/`(若设置了 `$XDG_CONFIG_HOME` 则为 `$XDG_CONFIG_HOME/ctty/backups/`) - **Windows**: `%APPDATA%\ctty\backups\`(回退:`%USERPROFILE%\.config\ctty\backups\`) **关键特性:** - 修改前自动备份 - 每个文件一个备份(覆盖之前的备份) - 单独存储以避免 SSH Include 冲突 - 需要时可手动恢复 **其他存储:** - **连接历史**:存储在同一配置目录中用于持久跟踪 - **端口转发历史**:保存的配置用于快速复用常用转发设置 **快速恢复:** ```bash # Unix/Linux/macOS cp ~/.config/ctty/backups/config.backup ~/.ssh/config # Windows copy "%APPDATA%\ctty\backups\config.backup" "%USERPROFILE%\.ssh\config" ``` ### 配置文件选项 默认情况下,ctty 使用 `~/.ssh/config` 中的标准 SSH 配置文件。可以使用 `-c` 标志指定其他配置文件: ```bash # TUI 模式使用自定义配置文件 ctty -c /path/to/custom/ssh_config # 命令使用自定义配置文件 ctty add hostname -c /path/to/custom/ssh_config ctty edit hostname -c /path/to/custom/ssh_config ctty move hostname -c /path/to/custom/ssh_config ``` ### 高级功能 #### 主机在配置文件间移动 ctty 提供强大的 `move` 命令在配置文件间迁移 SSH 主机。**此功能需要 SSH 配置中存在 Include 指令。** ```bash # 移动主机到其他配置文件(需要 Include 指令) ctty move my-server # 使用自定义配置文件移动(需要 Include 指令) ctty move my-server -c /path/to/custom/ssh_config ``` **⚠️ 重要要求:** - **SSH Include 指令必须存在** 于你的 SSH 配置文件中(`~/.ssh/config` 或用 `-c` 指定的文件) - 配置文件必须包含引用其他 SSH 配置文件的 `Include` 语句 - 没有 Include 指令时,move 命令会显示错误消息 **特点:** - **交互式文件选择器** - 从 Include 指令中选择目标配置文件 - **Include 支持** - 与 SSH Include 指令结构无缝协作 - **原子操作** - 自动备份的安全主机移动 - **验证** - 防止冲突并确保配置完整性 - **错误处理** - 需要 Include 文件但未找到时显示清晰消息 **使用场景:** - 从主配置重组主机到专门的 include 文件 - 将开发主机移到单独的环境特定配置 - 合并配置以更好地组织 **所需示例设置:** 你的主 SSH 配置文件必须包含 Include 指令,如: ```ssh # ~/.ssh/config Include ~/.ssh/config.d/* Include work-servers.conf Include projects/*.conf Host personal-server HostName personal.example.com User myuser ``` #### 实时连通性状态 ctty 具有异步 SSH 连通性检查功能,提供主机可用性的可视化指示: **状态指示:** - 🟢 **在线** - SSH 连接成功(显示响应时间) - 🟡 **连接中** - 正在测试连通性 - 🔴 **离线** - SSH 连接失败或主机不可达 - ⚫ **未知** - 状态尚未确定 **特点:** - **非阻塞检查** - 状态更新在后台进行 - **响应时间跟踪** - 在线主机显示连接延迟 - **自动刷新** - 状态指示持续更新 - **错误详情** - 连接失败的详细错误信息 #### 自动更新检查 ctty 内置版本检查功能,有可用更新时会通知你: **特点:** - **后台检查** - 版本检查异步进行,不阻塞启动 - **发布通知** - 有更新时显示清晰指示 - **预发布检测** - 识别 beta 和开发版本 - **GitHub 集成** - 直接链接到发布页面 - **无干扰** - 更新不会中断工作流 - **可配置** - 可在离线或断网环境中禁用 **更新通知出现在:** - 主 TUI 界面中作为微妙的通知 - 仅在有更新的稳定版本可用时 **禁用更新检查:** 通过 CLI 标志(一次性): ```bash ctty --no-update-check ``` 通过 `~/.config/ctty/config.json`(持久): ```json { "check_for_updates": false } ``` #### 自更新(Self-Update) 检测到新版本后,可以直接在 ctty 内完成升级: - **TUI 内** — 出现更新横幅时按 `U`,按 `y` 确认。下载 → 校验 → 安装过程在弹窗中实时显示,完成后重启 ctty 即可运行新版本。 - **命令行** — `ctty update` 仅检查新版本;`ctty update --yes` 下载并安装。 更新下载与安装脚本一致的发布包(`ctty__.tar.gz`,Windows 为 `.zip`),对照发布页的 `checksums.txt` 做 sha256 校验,并以原子方式替换当前可执行文件——即使更新中途被打断,也不会留下损坏的二进制。若可执行文件所在目录需要管理员权限,请用 sudo 重跑或修正该文件属主。 #### 从 Tabby 导入 把 [Tabby](https://tabby.sh) 里的 SSH 配置迁到 ctty 使用的 OpenSSH 配置: ```bash ctty import --from tabby ctty import tabby --dry-run ctty import tabby -f /path/to/tabby/config.yaml ``` `type: ssh` 的配置会追加到 `~/.ssh/config.d/tabby.conf`,必要时在 `~/.ssh/config` 里加上 `Include`。已存在的 `Host` 名称会跳过。Tabby 保险库里的密码不会导入——请用密钥,或在 ctty 里重新保存密码。 #### 端口转发历史 ctty 记住你的端口转发配置以便快速复用: **特点:** - **自动保存** - 成功的转发设置自动保存 - **快速复用** - 之前使用的配置作为建议出现 - **按主机历史** - 转发历史按 SSH 主机跟踪 - **所有转发类型** - 支持本地(-L)、远程(-R)和动态(-D)转发历史 - **持久存储** - 历史在应用重启后保留 ### 平台特定说明 **Windows:** - ctty 与内置 OpenSSH 客户端兼容(Windows 10/11) - 配置文件位置:`%USERPROFILE%\.ssh\config` - 兼容 WSL SSH 配置 - 支持 Unix 系统相同的 SSH 选项 **Unix/Linux/macOS:** - 标准 SSH 配置文件:`~/.ssh/config` - 完全兼容 OpenSSH 功能 - 自动保持文件权限 **Termux(Android):** - 由 `install/unix.sh` 安装器自动检测 - 安装到 `$PREFIX/bin`(如 `~/termux/files/usr/bin`),而非 `/usr/local/bin` - 无需 `sudo`,以 Termux 用户权限运行 - 架构检测(`aarch64 → arm64`、`armv7* → armv7`)选择 cgo 编译的 `ctty_Android_*` 发布包,走 Android 系统 DNS(纯 Go 解析在部分机器上会挂,如 `[::1]:53 connection refused`);已存密码保险库与 Linux 包共用 ## 🏗️ 配置 ctty 直接使用你的标准 SSH 配置文件(`~/.ssh/config`)。它添加特殊注释标签以增强功能,同时保持与标准 SSH 工具的完全兼容。 ### SSH Include 支持 ctty 完全支持 SSH Include 指令,允许跨多个文件组织 SSH 配置。这对于管理大量主机或按环境、项目、团队组织配置特别有用。 **Include 示例:** ```ssh # 主 ~/.ssh/config 文件 Host personal-server HostName personal.example.com User myuser # 包含工作相关配置 Include work-servers.conf # 包含目录中的所有配置 Include projects/* # 包含相对路径 Include ~/.ssh/configs/production.conf ``` **组织示例:** *work-servers.conf:* ```ssh # Tags: work, production Host prod-web-01 HostName 10.0.1.10 User deploy ProxyJump bastion.company.com # Tags: work, staging Host staging-api HostName staging-api.company.com User developer ``` *projects/client-alpha.conf:* ```ssh # Tags: client, development Host client-alpha-dev HostName dev.client-alpha.com User admin Port 2222 ``` **示例配置:** Include ~/.ssh/conf.d/* ```ssh # Tags: production, web, frontend Host web-prod-01 HostName 192.168.1.10 User deploy Port 22 IdentityFile ~/.ssh/production_key Compression yes ServerAliveInterval 60 # Tags: development, database Host db-dev HostName dev-db.company.com User admin Port 2222 IdentityFile ~/.ssh/dev_key StrictHostKeyChecking no UserKnownHostsFile /dev/null # Tags: production, backend Host backend-prod HostName 10.0.1.50 User app Port 22 ProxyJump bastion.company.com ProxyCommand ssh -W %h:%p Jumphost IdentityFile ~/.ssh/production_key Compression yes ServerAliveInterval 300 BatchMode yes ``` ### 支持的 SSH 选项 ctty 支持所有标准 SSH 配置选项: **内置字段:** - `HostName` - 服务器主机名或 IP 地址 - `User` - SSH 连接用户名 - `Port` - SSH 端口号 - `IdentityFile` - 私钥文件路径 - `ProxyJump` - 跳板机连接隧道(如 `user@jumphost:port`) - `ProxyCommand` - 跳板命令连接隧道(如 `ssh -W %h:%p Jumphost`) - `Tags` - 自定义标签(ctty 扩展);特殊标签 `hidden` 从 TUI 和 `ctty search` 中隐藏主机,但保持可通过 `ctty ` 连接 **额外 SSH 选项:** 你可以在交互式表单的 "SSH Options" 字段中添加任何有效的 SSH 选项。以命令行格式输入(如 `-o Compression=yes -o ServerAliveInterval=60`),ctty 会自动转换为正确的 SSH 配置格式。 **常用 SSH 选项:** - `Compression` - 启用/禁用压缩(`yes`/`no`) - `ServerAliveInterval` - 保活消息间隔(秒) - `ServerAliveCountMax` - 保活消息最大数量 - `StrictHostKeyChecking` - 主机密钥验证(`yes`/`no`/`ask`) - `UserKnownHostsFile` - known_hosts 文件路径 - `BatchMode` - 禁用交互式提示(`yes`/`no`) - `ConnectTimeout` - 连接超时(秒) - `ControlMaster` - 连接多路复用(`yes`/`no`/`auto`) - `ControlPath` - 控制套接字路径 - `ControlPersist` - 保持连接存活时长 - `ForwardAgent` - 转发 SSH agent(`yes`/`no`) - `LocalForward` - 本地端口转发(如 `8080:localhost:80`) - `RemoteForward` - 远程端口转发 - `DynamicForward` - SOCKS 代理端口转发 **表单中的示例用法:** ``` SSH Options: -o Compression=yes -o ServerAliveInterval=60 -o StrictHostKeyChecking=no ``` 会自动转换为: ```ssh Compression yes ServerAliveInterval 60 StrictHostKeyChecking no ``` ### 应用配置 ctty 支持配置文件来自定义行为,包括界面语言、快捷键、自动更新检查以及自定义标签颜色。你也可以直接在 TUI 界面中按 `S` 键打开设置面板进行可视化配置。 **配置文件位置:** - **Linux/macOS**: `~/.config/ctty/config.json`(遵循 `$XDG_CONFIG_HOME`) - **Windows**: `%APPDATA%\ctty\config.json` **示例配置:** ```json { "language": "zh_CN", "check_for_updates": true, "key_bindings": { "quit_keys": ["q", "ctrl+c"], "disable_esc_quit": false }, "tag_colors": { "prod": "#FF0055", "staging": "#FFAA00", "k8s": "#326CE5", "mine": "#00DDFF" } } ``` **可用选项:** - **language**: 界面语言,支持 `"auto"`(跟随操作系统语言)、`"zh_CN"`(简体中文)或 `"en"`(English)。默认:`"auto"`。 - **check_for_updates**: 布尔值,启用或禁用启动时的自动更新检查。默认:`true`。在离线机器上设为 `false` 可避免连接延迟。 - **key_bindings.quit_keys**: 退出应用的按键数组。默认:`["q", "ctrl+c"]` - **key_bindings.disable_esc_quit**: 布尔值,禁用 ESC 键退出应用。默认:`false`。适合 Vim 用户避免误按 ESC 退出。 - **tag_colors**: 标签自定义颜色 Hex 映射字典(如 `{"prod": "#FF0055"}`),优先级高于内置语义色及哈希分配色。 **Vim 用户:** 如果你经常误按 ESC 导致应用退出,将 `disable_esc_quit` 设为 `true`。这会禁用 ESC 作为退出键,同时保留其他所有功能。 **离线机器:** 如果 ctty 因连接 GitHub 时的 DNS 超时而启动缓慢,将 `check_for_updates` 设为 `false`。也可以使用 `--no-update-check` CLI 标志进行一次性覆盖,无需编辑配置文件。 **默认配置:** 如果没有配置文件,ctty 会自动创建一个保持向后兼容的默认配置。 ## 🛠️ 开发 ### 前置要求 - Go 1.23+ - Git ### 从源码构建 ```bash # 克隆仓库 git clone https://github.com/zsuroy/ctty.git cd ctty # 构建二进制 go build -o ctty . # 运行 ./ctty ``` ### 项目结构 ``` ctty/ ├── main.go # 应用入口 ├── cmd/ # CLI 命令 (Cobra) │ ├── root.go # 根命令、CLI 标志与交互模式 │ ├── add.go # 添加主机命令 │ ├── edit.go # 编辑主机命令 │ ├── move.go # 移动主机命令 │ ├── search.go # 搜索命令 │ ├── serial.go # 串口管理命令 │ ├── telnet.go # Telnet 管理 / 直连命令 │ ├── sftp.go # SFTP 文件传输命令 │ ├── ftp.go # FTP 站点管理 / 浏览器命令 │ ├── webdav.go # WebDAV 站点管理 / 浏览器命令 │ ├── info.go # 机器可读 JSON 主机信息 │ └── completion.go # Shell 补全脚本生成 ├── internal/ │ ├── config/ # SSH 与应用配置管理 │ │ ├── ssh.go # SSH 配置解析、修改与 Include 展开 │ │ └── appconfig.go# 应用设置 (~/.config/ctty/config.json) │ ├── connectivity/ # SSH 连通性检查 │ │ └── ping.go # 异步 SSH ping 功能 │ ├── history/ # 连接历史跟踪 │ │ └── history.go # 历史管理和最后登录跟踪 │ ├── i18n/ # 多语言国际化与系统语言探针 │ │ ├── i18n.go # 核心翻译引擎与状态 │ │ ├── locales.go # 中英文双语语言字典 │ │ ├── detect_darwin.go # macOS AppleLocale 系统语言检测 │ │ ├── detect_windows.go # Windows Win32 API 语言检测 │ │ └── detect_other.go # Linux 环境变量与 Android getprop │ ├── serialconfig/ # 串口设备配置和连接 │ │ ├── serial.go # 设备配置存储 (~/.config/ctty/serial.json) │ │ ├── ports.go # 端口枚举和辅助函数 │ │ ├── connect.go # 串口连接桥接 (ExecCommand) │ │ ├── raw_unix.go # POSIX raw 终端模式 (x/term) │ │ └── raw_windows.go # Windows raw 终端模式 (x/term) │ ├── rawterm/ # 串口与 telnet 共享的 raw 模式辅助包 │ │ └── rawterm.go # 基于 x/term 的 MakeRaw / Restore 封装 │ ├── telnetconfig/ # Telnet 设备配置 │ │ └── telnet.go # 设备配置存储 (~/.config/ctty/telnet.json,原子写入) │ ├── telnetclient/ # 原生 RFC 854 telnet 客户端 │ │ └── telnet.go # IAC 状态机、协商与交互桥接 │ ├── sftpconfig/ # SFTP 客户端引擎与文件传输 │ │ └── client.go # SFTP 会话、上传、下载与目录遍历 │ ├── ftpconfig/ # FTP 站点清单 (~/.config/ctty/ftp.json) │ ├── ftpclient/ # 纯 FTP 传输层(列表、下载、上传、新建、删除、重命名) │ ├── ftpcred/ # FTP 密码的加密保险库存储(ftp: 前缀) │ ├── webdavconfig/ # WebDAV 站点清单 (~/.config/ctty/webdav.json) │ ├── webdavclient/ # WebDAV 传输层(列表、下载、上传、新建、删除、重命名) │ ├── webdavcred/ # WebDAV 密码的加密保险库存储(webdav: 前缀) │ ├── version/ # 版本检查和更新 │ │ ├── version.go # GitHub 发布检查和版本比较 │ │ └── version_test.go # 版本解析和比较测试 │ ├── ui/ # 终端 UI 组件 (Bubble Tea) │ │ ├── tui.go # 主 TUI 界面和程序设置 │ │ ├── model.go # 核心 TUI 模型和状态 │ │ ├── update.go # 消息处理和状态更新 │ │ ├── view.go # UI 渲染和布局 │ │ ├── table.go # 主机列表表格组件、状态指示与 Tag 色彩渲染 │ │ ├── tag_color.go# 语义化与哈希色彩算法 │ │ ├── add_form.go # 添加主机表单界面 │ │ ├── edit_form.go# 编辑主机表单界面 │ │ ├── move_form.go# 移动主机表单界面 │ │ ├── info_form.go# 主机详情弹窗 │ │ ├── help_form.go# 键盘快捷键帮助弹窗 │ │ ├── settings_form.go # 系统设置与偏好配置弹窗 │ │ ├── port_forward_form.go # 端口转发设置和历史 │ │ ├── styles.go # Lip Gloss 样式定义 │ │ ├── sort.go # 排序和过滤逻辑 │ │ ├── serial_form.go # 串口设备列表 UI │ │ ├── serial_add_form.go # 添加串口设备表单 │ │ ├── serial_connect_form.go # 连接前参数编辑表单 │ │ ├── telnet_form.go # Telnet 设备列表 UI(含可达性探测) │ │ ├── ftp_sites.go # FTP 站点管理器 UI │ │ ├── ftp_view.go # FTP 本地|远端双栏浏览器 UI │ │ ├── webdav_sites.go # WebDAV 站点管理器 UI │ │ ├── webdav_view.go # WebDAV 双栏文件浏览器 UI │ │ └── sftp_view.go # SFTP 远程与本地双模文件浏览器 │ └── validation/ # 输入验证 │ └── ssh.go # SSH 配置验证 ├── images/ # 文档资源 │ ├── logo.svg # 项目 logo │ └── ctty.gif # 演示动画 ├── install/ # 安装脚本 │ ├── unix.sh # Unix/Linux/macOS 安装器 │ └── README.md # 安装指南 ├── .github/ # GitHub 配置 │ ├── copilot-instructions.md # 开发指南 │ └── workflows/ # CI/CD 流水线 │ └── release.yml # GoReleaser 发布 ├── go.mod # Go 模块定义 ├── go.sum # Go 模块校验 ├── .goreleaser.yaml # GoReleaser 配置 ├── LICENSE # MIT 许可证 ├── CHANGELOG.md # 变更记录 ├── README.md # 项目文档(英文) └── README_CN.md # 项目文档(中文) ``` ### 依赖 - [Cobra](https://github.com/spf13/cobra) - CLI 框架 - [Bubble Tea](https://github.com/charmbracelet/bubbletea) - TUI 框架 - [Bubbles](https://github.com/charmbracelet/bubbles) - TUI 组件 - [Lipgloss](https://github.com/charmbracelet/lipgloss) - 样式 - [Go Crypto SSH](https://golang.org/x/crypto/ssh) - SSH 连通性检查 - [go.bug.st/serial](https://github.com/bugst/go-serial) - 跨平台串口通信 ## 📦 发布 自动为多平台构建发布版本: | 平台 | 架构 | 下载 | |------|------|------| | Linux | AMD64 | [ctty_Linux_x86_64.tar.gz](https://github.com/zsuroy/ctty/releases/latest/download/ctty_Linux_x86_64.tar.gz) | | Linux | ARM64 | [ctty_Linux_arm64.tar.gz](https://github.com/zsuroy/ctty/releases/latest/download/ctty_Linux_arm64.tar.gz) | | macOS | Intel | [ctty_Darwin_x86_64.tar.gz](https://github.com/zsuroy/ctty/releases/latest/download/ctty_Darwin_x86_64.tar.gz) | | macOS | Apple Silicon | [ctty_Darwin_arm64.tar.gz](https://github.com/zsuroy/ctty/releases/latest/download/ctty_Darwin_arm64.tar.gz) | | Windows | AMD64 | [ctty_Windows_x86_64.zip](https://github.com/zsuroy/ctty/releases/latest/download/ctty_Windows_x86_64.zip) | ## 🤝 贡献 欢迎贡献!请随时提交 Pull Request。对于重大更改,请先开 issue 讨论你想更改的内容。 ### 开发流程 1. **Fork** 仓库 2. **创建** 功能分支(`git checkout -b feature/amazing-feature`) 3. **提交** 你的更改(`git commit -m 'Add amazing feature'`) 4. **推送** 到分支(`git push origin feature/amazing-feature`) 5. **提交** Pull Request ## 📝 许可证 本项目基于 MIT 许可证 —— 详见 [LICENSE](LICENSE) 文件。 ## 🙏 致谢 本项目是 [SSHM](https://github.com/Gu1llaum-3/sshm) 的 Fork,由 [@Gu1llaum-3](https://github.com/Gu1llaum-3) 创建。我们感谢使 ctty 成为可能的原始工作。 - [Charm](https://charm.sh/) 提供优秀的 TUI 库 - [Cobra](https://cobra.dev/) 提供出色的 CLI 框架 - [@Gu1llaum-3](https://github.com/Gu1llaum-3) 创建了 sshm,ctty 的 ssh 管理基础 - [@yimeng](https://github.com/yimeng) 贡献 SSH Include 指令支持 - [@ldreux](https://github.com/ldreux) 贡献多词搜索功能 - [@qingfengzxr](https://github.com/qingfengzxr) 贡献自定义快捷键支持 - [Linux.do](https://linux.do) · [V2ex](https://v2ex.com) 开源社区支持 - Go 社区构建了这些出色的工具 ## Star History Star History Chart ---
**由 [zsuroy](https://github.com/zsuroy) 用 ❤️ 制作** ⭐ **如果对你有用,请给个 Star!** ⭐