Files
shell-rs/docs/manual.md
T
XuzandClaude Opus 5.5 e09adeefb7 外部 CLI 新增 exec --terminal:在已打开的终端里执行命令
只允许登录一次的堡垒机(外部连接)上,exec 重新登录会被拒绝,另开通道又会结束会话。
--terminal 把命令打进这台主机在 ShellRS 里已打开的远程终端:先发 Ctrl-C,探测出
交互 shell(bash、dash、busybox ash)后输入命令行,经 OSC 标记取回输出、退出码和
执行上下文(--json 的 context)。不做忙碌检测,只拒绝全屏程序和同一终端已有一次运行。
外部连接上普通 exec 登录失败时,说明里提示改用 --terminal。

shells.yml 在 Docker 里对 bash 4.2–5.2、dash、busybox ash 跑真实终端测试。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:16:30 +08:00

73 KiB
Raw Blame History

ShellRS 使用手册

返回 README

基于 GPUI Kit 的中文 SSH 主机管理工具,提供持久化的主机与分组、可在多台主机间共用的登录凭据、本地终端、SSH 多终端、对标 WinSCP 的 SFTP 双栏浏览器和 SSH 端口转发。

标题栏「ShellRS」后面的三个图标切换左侧栏显示的内容:主机列表、端口转发列表或凭据列表。侧栏隐藏时点其中一个会把它重新展开。

ShellRS 同一时间只运行一个:已经开着时再打开一次,会把已有的窗口调到前面,新启动的那个随即退出。两个 ShellRS 各自把主机读进内存再写回同一个数据库,会互相覆盖对方的改动。(用 SHELLRS_DATA_DIR 指到不同数据目录的算不同的 ShellRS,可以同时运行。)要并排看两个终端或 SFTP,把标签拖成分栏即可。

在 macOS 上,点窗口左上角的关闭按钮只是把 ShellRS 隐藏到后台:已打开的连接、SFTP 传输、端口转发和外部 CLI 照常运行,点 Dock 图标恢复窗口,原来的标签都在。要真正退出用 ⌘Q,或者右键 Dock 图标选「退出」。Windows 和 Linux 上关闭窗口就是退出。

主机列表

左侧栏里保存的每一项是一台主机:地址、端口和认证方式。同一台机器用不同用户登录,就保存成两台主机。

主机对话框的「认证方式」有三种:

  • 密码:填用户名和密码,密码保存在系统钥匙串;密码留空则每次连接时询问。只用密码登录,不会先拿 SSH Agent 或私钥去试。
  • 使用凭据:选一条保存好的凭据,用户名和登录方式都来自凭据(见下面「凭据」),对话框里不再填用户名和密码。「测试连接」同样使用凭据保存的密码。要用私钥登录,就建一条密钥凭据。
  • 无密码:只填用户名。依次尝试服务器免认证、SSH Agent 和 ~/.ssh 下的默认私钥(id_ed25519、id_ecdsa、id_rsa),和命令行 ssh 默认的做法一样。服务器要求密码时连接失败并说明原因,不会询问;服务器在密钥之后再要验证码时照样询问。

无论选哪种,连接时都先问服务器是否允许免认证登录,允许就直接登录。「测试连接」时选了「密码」却没填,就像「无密码」那样试一遍(免认证、SSH Agent、默认私钥),连不上就说明原因。

主机对话框「分组」下面的「连接方式」决定怎么连到这台主机,终端、SFTP、端口转发、外部 CLI 和「测试连接」都照它走:

  • 直接连接:默认,本机直接连主机的地址和端口。
  • SSH 跳板:经过别的已保存主机连过去,支持多级。框里一排标签写出整条路(「本机 → 阿里云99 → 禅道 → 当前主机」),下面每台跳板一行,「×」移除,「添加跳板主机」可按名称或地址搜索;要调顺序就移除后重新添加。连接时先登录第 1 台,由它连第 2 台,依此类推,最后一台连到主机。每台跳板都用它自己的地址、端口、认证方式(密码、凭据或无密码)和主机信任记录,首次连接各问一次主机密钥,询问框里写明是哪台跳板主机;跳板主机自己的「连接方式」在这里不生效,要多级就在这里按顺序列出。主机的地址按跳板主机那边的网络来填,例如内网地址。
  • 代理连接:经由 HTTP 代理(CONNECT)或 SOCKS5 代理连接,在下拉框里选。填代理的地址和端口(例如本机的 127.0.0.1:7890);代理需要认证时再填用户名和密码,密码保存在系统钥匙串,经由同一个代理、同一个用户名的主机共用。主机的地址交给代理去解析。代理要求认证却没有密码、或者拒绝了用户名和密码时,连接失败并说明原因,不会询问。

改了一台主机的地址或认证方式,经由它跳转的主机也会重新连接(只改名称不会)。删除一台被别的主机用作跳板的主机,确认框写明有几台主机在用它;删除后那些主机的跳板列表里留下一行「已删除的主机」,连接时直接报错,不会悄悄改成直连或少跳一级,编辑时移除或换一台即可。已经打开的连接不受影响。

尚未实现:跳板和代理叠加使用、拖动调整跳板顺序、HTTPS 代理、在主机列表里标出连接方式。

对话框最后是「备注」,可以写多行(回车换行),记下机器的用途、负责人、到期时间之类,只保存在本地数据库里,不影响连接。

鼠标停在主机上,行的右侧会显示 用户@地址:端口,主机有备注时下面接着显示备注(太长的只显示前 6 行)。右键主机可连接、打开 SFTP、编辑、复制、复制 IP 地址(地址是域名时叫「复制主机名」)、复制 ID 或删除。「复制 ID」复制的是主机的 16 位随机标识(形如 Jwg5rHvXCxw89paM),供其他工具标识这台主机:它在主机创建时生成,改名、改地址都不变,复制出来的主机得到新的 ID,删掉的 ID 不会再分配。没有打开任何标签时,中间区显示「最近连接」列表,双击或回车连接;右键其中的主机弹出同一个菜单,并选中该主机。

列表上方「新建主机…」左边的「快速连接」打开一个搜索框,列出所有保存的主机:最近连接过的在前,其余按名称排,每行写着分组和 用户@地址:端口。输入名称、地址、用户名、备注或分组里的字就能筛选,几个词用空格隔开时都要匹配。打开时不高亮任何一台;输入后高亮第一个匹配的,回车就连它;也可以 ↑↓ 移动,或者直接单击一台连接。

列表上方的搜索框(⌘K,其他平台 Ctrl+K)按名称、地址、用户名筛选主机,也按名称找分组:分组名匹配时列出这个分组和它下面的全部子分组、主机。结果都展开,匹配的主机连同它所在的各级分组一起显示。回车连接第一台匹配的主机(按列表里的顺序;只因分组匹配而列出的主机不算)。Esc 清空搜索。

拖动分组或主机到同类项目的上侧 / 下侧可调整同级顺序;主机拖到分组会移入该分组,分组拖到另一个分组的中部会成为子分组。拖到列表空白处可移回根层级。分组始终排在同级主机之前,顺序与分组的展开状态会保存到本地数据库。搜索时暂停拖动排序。

临时连接

标题栏右上角的「临时连接…」连一台主机而不保存它,适合只登一次的机器。对话框和新建主机一样填地址、端口和认证方式(密码、使用凭据或无密码),没有分组、连接方式和备注,名称可以不填(用地址);可以先「测试连接」。点「连接」打开一个终端标签:

  • 功能齐全:在新标签页中连接、打开 SFTP、重新连接和右侧栏的全部工具都能用。连接方式是直接连接。
  • 不保存:不进主机列表、开始页的最近连接和数据库;它的终端和 SFTP 标签都关掉后就没了。标签的菜单里没有「编辑主机…」。
  • 密码只在内存里:填的密码不进钥匙串,重新连接时照样用它;没填时服务器要密码就弹框问。选「使用凭据」时用凭据保存的密码或私钥。
  • 外部 CLI 的 shellrs hosts list 也列出它(JSON 里 "temporary": true,表格的分组一栏写「(未保存)」),标签开着时可以用它的 ID。

要保存的主机在主机列表标题栏的「+」、右键菜单或 ⌘N(其他平台 Ctrl+N)新建。

端口转发

点标题栏的端口转发图标,左侧栏换成转发列表。每条转发规则经由一台已保存的主机,启动时为自己建立一条 SSH 连接,不依赖该主机的终端或 SFTP 标签:关掉标签、对主机「断开连接」都不影响它,主机的连接状态也不把它算在内。有转发在运行时,标题栏的端口转发图标旁显示运行数量。

三种转发,都按「入口 → 出口 → 目标」理解,连接从入口进、经 SSH 隧道到出口、再由出口去连目标:

类型 入口(监听) 出口 用途
本地转发(ssh -L) 本机 服务器 在本机访问服务器那边的服务,例如用本机的客户端连只对服务器开放的数据库
远程转发(ssh -R) 服务器 本机 让服务器那边访问本机的服务,例如把本机开发中的站点给对方看、接收 Webhook
动态转发(ssh -D) 本机(SOCKS 代理) 服务器 把服务器当代理,目标由应用自己指定,例如让浏览器经由服务器上网
  • 新建和编辑:列表标题栏的「+」打开对话框。上方一行三张卡片选类型,中间的示意图随表单实时填入地址、标出入口在哪台机器上,下面一句话说明这条规则的效果(如「在本机连接 127.0.0.1:8080,就等于从 SSH 服务器连接 db.internal:3306。」)。示意图和这句话里的「SSH 服务器」就是「经由主机」选的那一台,图里按它扮演的角色称呼,不写主机的名称。示意图上有一个圆点沿连接方向缓缓移动:先过 SSH 隧道,再到目标,停一下,周而复始;切换类型时从新的入口重新出发。名称可以不填,列表里显示转发摘要(8080 → db.internal:3306、9000 ← localhost:3000、SOCKS 1080)。
  • 启动和停止:每行末尾的按钮,或双击该行、选中后回车;右键菜单里还有编辑和删除。「创建」只保存规则,不会自动启动。勾选「启动 ShellRS 时自动开启」的规则随应用启动。
  • 状态:行尾显示正在连接、运行中(及当前连接数)、正在重连或已停止的原因。某个连接转发不了(例如服务器连不上目标)只在该行提示,转发本身继续运行。
  • 登录:使用主机的配置、钥匙串里保存的密码和 ShellRS 自己的主机信任记录。首次连接的主机、需要输入的密码会弹出和终端一样的询问框,并注明是哪条转发在连接;取消询问等于停止这条转发。
  • 断线重连:连接中断后按 1、3、10 秒自动重连三次,重连期间本机监听端口保留,新进来的连接会被直接关闭。自动重连不弹任何询问:需要重新输入密码、确认主机密钥时停止并写明原因,手动启动即可。三次都失败也会停止,并弹出通知。
  • 修改后:编辑运行中规则的类型、主机、监听或目标,或编辑它所经由的主机的地址、认证方式和连接方式(包括这台主机所用凭据的用户名、类型或私钥文件,以及它的跳板主机),这条转发会按新设置重新启动;只改名称或自动开启不会。
  • 删除主机:删除主机(或包含它的分组)会连同经由它的转发规则一起删除,运行中的先停止,确认框里写明数量。
  • 动态转发支持 SOCKS5(无认证,CONNECT,IPv4、域名、IPv6)和 SOCKS4 / 4a。域名交给服务器解析。
  • 监听地址默认 127.0.0.1。填其他地址时,本地和动态转发会被同一网络中的其他设备使用;远程转发需要服务器的 sshd_config 设置 GatewayPorts clientspecified 或 yes,其他机器才连得上;默认是 no,这时转发照常运行、不报错,但只监听服务器自己的 127.0.0.1(和手写 ssh -R 一样)。对话框在填了非回环地址时会提示这一点。1024 以下的端口需要管理员(服务器上是 root)权限。不支持端口 0(由系统挑选端口)。

尚未实现:通过外部 CLI 管理转发、规则排序。系统的「减少动态效果」设置目前不会关掉示意图的动画。

凭据

点标题栏的凭据(钥匙)图标,左侧栏换成凭据列表。一条凭据是一套可以让多台主机共用的登录信息,包括名称、用户名和登录方式:

类型 保存什么 登录时
密码 用户名和密码 用凭据保存的密码;没存或被拒绝时询问
密钥 用户名、私钥和口令 只用这把私钥;口令按私钥文件保存,用同一个文件的凭据共用
SSH Agent 用户名 只用 SSH Agent 中的密钥:macOS / Linux 上是 SSH_AUTH_SOCK 指向的 Agent,Windows 上是 OpenSSH Authentication Agent 服务
  • 新建和编辑:列表标题栏的「+」、空列表里的「新建凭据…」或空白处的右键菜单打开对话框;双击凭据、选中后回车或右键「编辑凭据…」编辑。密码和私钥口令存进系统钥匙串,数据库里只有名称、用户名、类型和私钥路径。
  • 密钥从哪里来:密钥凭据的「私钥」有三种来源。
    • 本机文件:选一个私钥文件,只保存它的路径;文件移动或删除后需要重新选择。
    • 粘贴:贴进 OpenSSH、PEM 或 PuTTY 格式的私钥。贴成公钥或认不出的内容时会说明原因。私钥加了口令时才显示口令栏。
    • 生成新密钥:选 Ed25519(默认)或 RSA 4096,选中就生成;对话框里显示公钥,旁边可以复制。口令可留空;填了就用它加密私钥,口令存进钥匙串。生成的密钥以凭据名称作为注释。
    • 粘贴和生成的私钥由 ShellRS 写成数据目录下 keys/ 里的文件(随机文件名,只有自己的账户能读),凭据引用这个文件,编辑时显示为「本机文件」和它的路径。之后再粘贴或生成会直接覆盖这个文件,已连接的主机不会因此重连;改成别的文件或别的类型、或删除凭据时,这个文件连同它的口令一起删除,对话框会先提示。用户自己的私钥文件 ShellRS 从不改动或删除。
    • 空列表和空白处的右键菜单里另有「生成密钥…」,打开的是同一个对话框,已经选好「密钥 · 生成新密钥」。密钥凭据的右键菜单有「复制公钥」,用来把公钥加到服务器的 ~/.ssh/authorized_keys。
  • 主机跟着凭据变:改凭据的用户名,所有使用它的主机的用户名一起变。改用户名、类型或私钥文件时,使用它的已连接主机会重新连接(只改名称不会);对话框里写明有几台主机在用。
  • 删除:右键「删除」。有主机在用时确认框写明数量和它们之后怎么登录:用密码凭据的主机改为「密码」,连接时询问;用密钥或 SSH Agent 凭据的主机改为「无密码」。用户名不变,密码和私钥不会复制过去。已经打开的连接不受影响,凭据的密码随凭据一起从钥匙串删除。
  • SSH Agent 凭据连不上 Agent、Agent 里没有密钥或服务器不接受其中任何一把时,会直接说明原因,不会改为询问密码。「无密码」的主机也会尝试同一个 Agent,连不上时静默跳过,接着试默认私钥(Windows 上同样如此)。

尚未实现:在主机对话框里直接新建凭据、凭据排序、自定义 SSH Agent 的套接字、把公钥自动装到主机上、导出 ShellRS 保存的私钥。

设置

侧栏最下方的「设置」按钮(或 ⌘,,其他平台 Ctrl+,)在中间区打开「设置」标签页;已经打开时切换到该标签,不会重复打开。设置页分两栏:左边是分类(外观、终端、关键字高亮、键盘快捷键、外部 CLI、应用、关于),上方可搜索,栏宽可拖动;右边是所选分类的设置。设置改动立即生效并保存在数据目录的 settings.json 里。

  • 外观 → 常规 → 界面语言:跟随系统、简体中文、English,默认跟随系统:系统语言是中文时用简体中文,其他语言用英文。改动立即生效,不用重启:窗口里的文字、已打开的标签和搜索框提示一起换成新的语言;已经写进终端的提示和已经弹出的通知保持原样。外部 CLI 的输出也用这里的语言。
  • 外观 → 常规 → 应用外观:深色、浅色、跟随系统,默认跟随系统;选「跟随系统」时随系统的深浅色切换。标题栏的主题按钮也会改写这一项。
  • 外观 → 主题:左栏是浅色主题,右栏是深色主题,各选一套:应用外观为浅色时用左栏选中的那套,深色时用右栏的;跟随系统时随系统一起切换,标题栏的主题按钮切换时也一样。默认只有终端按所选主题配色,界面保持中性的灰色调(深色是不刺眼的炭灰,不是纯黑);打开上方的「界面跟随主题」,界面也按主题配色:侧栏、标签栏、对话框等用主题的底色和文字色,成功、警告、错误等状态用主题的绿、黄、红。每张卡片用该主题的颜色显示一段示例,选中的右上角有蓝色对勾。默认是 ShellRS Light 和 ShellRS Dark,与界面同色。内置浅色、深色各 10 套:浅色 ShellRS Light、Solarized Light、Tokyo Day、Catppuccin Latte、Flexoki Light、One Half Light、Gruvbox Light、Kanagawa Lotus、Rosé Pine Dawn、Everforest Light;深色 ShellRS Dark、Solarized Dark、Tokyo Night、Catppuccin Mocha、Flexoki Dark、One Half Dark、Gruvbox Dark、Kanagawa Wave、Dracula、Nord。同一主题的浅色版和深色版在两栏的同一行。改动立即作用于所有已打开的终端,字体和关键字高亮的预览也用当前主题;vim 等程序询问终端的背景色时,得到的是当前主题的颜色。尚未实现:自定义主题、导入配色、按主机指定主题。
  • 终端 → 字体配置:字体(只列出本机安装的等宽字体,默认是系统的等宽字体,macOS 上为 Menlo)、字号(10–28 像素,默认 13)、行高(字号的 1.0–2.0 倍,默认 1.54,即原来的 20 像素行高)。改动立即作用于所有已打开的终端;在终端里按 ⌘= / ⌘-(其他平台 Ctrl)也能逐级调字号,⌘0 回到默认。下方的预览按终端的排法显示字母、数字、易混字符、符号、中文、制表符和一行命令。设置文件里的字体在本机没有安装时,使用默认字体。
  • 关键字高亮:总开关、预览和规则表,终端里按规则给文字上色、匹配时提醒,见「终端」一节。
  • 键盘快捷键:主要功能的快捷键,分通用、标签、终端、编辑器四组,每行是功能名和它的按键。点按键进入「按下组合键」,按下新的组合就换上;Esc 或点别处放弃。行尾两个按钮:禁用(之后显示「无」,再点一下恢复默认)、恢复默认;页面上方的「重置」也能逐项恢复。改动立即生效,工具栏提示和右键菜单里显示的按键跟着变。
    • 组合键要带 ⌘、⌥ 或 ⌃(其他平台 Ctrl 或 Alt),或者是 F1–F12;「切换到标签 1…9」按任意一个带修饰键的数字即可,九个一起换。
    • 已被同一处的另一个快捷键、或输入框等内置功能占用的组合会被拒绝,并提示被谁占用;想换就先改或禁用那一个。终端、编辑器里的快捷键可以和通用快捷键同键,在终端、编辑器里以前者为准(如 ⌘K 在终端里是清屏)。
    • 默认(macOS / 其他平台):新建主机 ⌘N / Ctrl+N,新建分组 ⌘⇧N / Ctrl+Shift+N,打开设置 ⌘, / Ctrl+,,显示或隐藏侧栏 ⌘B / Ctrl+B,显示或隐藏右侧栏 ⌘⌥B / Ctrl+Alt+B,聚焦搜索 ⌘K / Ctrl+K,放大、缩小界面和实际大小 ⌘= ⌘- ⌘0 / Ctrl+= Ctrl+- Ctrl+0,退出 ⌘Q / Ctrl+Q;新建本地终端 ⌘T / Ctrl+T,关闭标签 ⌘W / Ctrl+W,下一个标签 ⌘⇧] / Ctrl+Tab,上一个标签 ⌘⇧[ / Ctrl+Shift+Tab,切换到标签 1…9 ⌘1…⌘9 / Alt+1…9(9 是最后一个);终端的复制、粘贴、查找、查找下一个、查找上一个、清屏 ⌘C ⌘V ⌘F ⌘G ⌘⇧G ⌘K / Ctrl+Shift+C、Ctrl+Shift+V、Ctrl+Shift+F、F3、Shift+F3、Ctrl+Shift+K,放大、缩小字号和默认字号 ⌘= ⌘- ⌘0 / Ctrl+= Ctrl+- Ctrl+0;编辑器保存 ⌘S / Ctrl+S。标签切换在当前标签所在的那组标签里进行,首尾循环。⌘= / ⌘- / ⌘0 在终端里调终端字号(每次 1 像素,范围同「终端 › 字号」的 10–28,写进设置,下次启动保留),在终端外缩放整个界面(五档,重启后回到默认)。
    • SFTP 文件列表、图片预览的快捷键和 Enter、方向键、Tab、Esc 这些固定键不在这里改。
  • 外部 CLI:见下一节。
  • 应用 → 窗口:「记住窗口大小」恢复上次的窗口大小和最大化状态,「记住窗口位置」把窗口放回上次所在的屏幕和位置,默认都打开,下次启动时生效。那块屏幕不在了、或窗口大半在屏幕外时,放在屏幕中间;窗口比屏幕大时缩到能放下。全屏不记,按退出全屏后的大小恢复。窗口的大小和位置随移动随时记在数据目录的 window.json 里。
  • 关于:「应用更新」一组:当前版本和检查更新、更新渠道、自动升级,见「下载与更新」;「隐私」一组的「发送匿名使用统计」,默认打开,见「隐私」;「ShellRS」一组的「官网」用浏览器打开 shellrs.com。

外部 CLI

shellrs 命令让 Codex、Claude Code、OpenCode 等 AI Agent 在 ShellRS 里已保存的主机上执行远程命令、传输和同步文件,也能查看、新建、修改和删除主机与凭据。命令本身不读密码和私钥,也不读数据库:它把请求交给正在运行的 ShellRS,由 ShellRS 用保存的配置和钥匙串去连接。请求走本机的进程间通信:macOS、Linux 上是数据目录下的套接字 cli.sock,Windows 上是命名管道 \\.\pipe\shellrs-cli-<数据目录的散列>。

在 设置 → 外部 CLI 中:

  • 启用外部 CLI:默认关闭。关闭时 ShellRS 仍在监听,但拒绝所有请求,命令会提示去这里打开。开启后,本机当前用户下的任何程序都能这样使用已保存的主机,也能修改主机和凭据,还能在已打开的远程终端里输入命令(exec --terminal,包括已切到 root 的终端),都没有另外的开关。套接字只对当前用户可读写,连接时还会核对对方的用户身份;Windows 的管道同样只允许当前用户、只接受本机连接,命令在发请求之前还会确认管道属于当前用户(或管理员),防止别人抢注同名管道。
  • CLI 二进制:把 shellrs 放进 PATH。
    • macOS:链接到 /usr/local/bin/shellrs,目录不可写时弹系统授权框。
    • Linux:链接到 ~/.local/bin/shellrs。
    • macOS、Linux 上「移除」只删除指向 shellrs 的链接,同名的其他文件不会被改动。
    • Windows:图形程序没有控制台,命令是单独的控制台程序 shellrs-cli.exe(与 shellrs.exe 放在一起)。「安装」把它复制成 %LOCALAPPDATA%\ShellRS\bin\shellrs.exe,并把这个文件夹加入当前用户的 PATH(不需要管理员),重新打开的终端和 Agent 才能找到它。ShellRS 升级后启动时会自动更新这份副本;更新不了时显示「更新」。副本正被使用时也能更新。「移除」删掉副本并把文件夹移出 PATH。
  • Agent Skills:把教 Agent 使用 shellrs 的 skill 写到通用目录(~/.agents/skills)或 Codex、Claude Code、OpenCode、WorkBuddy 各自的 skills 目录;内容和当前版本不同时显示「更新」。「复制 skills」把 skill 全文复制到剪贴板。

命令(shellrs --help 查看完整说明):

shellrs hosts list [-q <关键词>] [--json]      # 列出主机;输出不是终端时自动用 JSON
shellrs hosts show <ID> [--json]               # 一台主机的全部配置
shellrs exec <ID> "<命令>"                     # 或 --stdin 从标准输入读命令
shellrs exec --json                            # 从标准输入读 {"host", "command"},输出 JSON
shellrs exec <ID> --terminal "<命令>"          # 在 ShellRS 已打开的终端里执行,见下文
shellrs upload <ID> <本地路径> <远程路径>
shellrs download <ID> <远程路径> <本地路径>
shellrs sync <ID> <本地目录> <远程目录> [--delete]
shellrs hosts create | update <ID> | delete <ID> [--force]
shellrs credentials list | show <ID> | create | update <ID> | delete <ID>
  • <ID> 是 16 位的主机 ID,即 shellrs hosts list 的 id,也就是主机右键「复制 ID」复制的内容。列表里还有标签开着的临时连接和外部连接("temporary": true),见「临时连接」和「从堡垒机打开(外部连接)」。
  • exec 每次临时建立连接,执行完即断开。远程命令没有标准输入,退出码就是远程命令的退出码;被信号终止时是 128 加信号编号。
  • exec --terminal(exec --json 里写 "terminal": true)不重新登录,而是把命令打进这台主机在 ShellRS 里已打开的远程终端,给只允许登录一次的堡垒机用(见「从堡垒机打开(外部连接)」)。它先发 Ctrl-C,打断终端里正在运行的程序、清掉输入行里没提交的内容,再输入一行探测和一行命令;这两行和命令的输出都显示在终端里。命令在终端当前的用户、目录和机器上执行(su、sudo -i、嵌套 ssh 之后也是),--json 的结果多一项 context(user、host、cwd、shell、interp)写明在哪里。命令的输出经管道,程序看不到终端:没有颜色和分页器,stderr 并进 stdout;命令没有标准输入,要密码的程序会停在终端里等。用哪个终端:右侧栏正对着的终端是这台主机的就用它,否则用这台主机最新的、已连接的终端。
    • 只支持 Linux 上的 bash、dash 和 busybox ash(否则报 unsupported_shell)。编码后的命令行,bash 和 dash 最多 4000 字节,busybox 最多 1000 字节(否则报 too_long)。
    • 以下情况报 terminal_busy,命令没有执行:全屏程序(vim、less、top、tmux 等)占着终端;上一条 --terminal 命令还没结束;5 秒内 shell 没有回应(前台程序不理 Ctrl-C,如 python、mysql);15 秒内 shell 没有开始执行(可能被堡垒机的命令过滤或复核拦下,这时会再发一次 Ctrl-C)。终端没打开或没连接报 no_terminal。
    • 执行过程中没有时限;命令行工具中途被结束时(如 Agent 超时),终端里的命令收到 Ctrl-C。
    • 那两行行首有空格,bash 设了 ignorespace 时不记进历史,否则会记下。停在不带提示的 read -s、或 vi 编辑模式的命令模式时认不出,会报「没有回应」。
  • 上传和下载沿用 SFTP 标签的传输引擎(递归、.filepart、断线重连),目标路径按 scp 的规则:目标是已存在的目录就放进去并保留原名,否则目标就是副本自己的路径,其父目录必须存在。已存在的文件直接覆盖;新建的文件保留源文件的可执行权限。~ 表示登录目录。
  • sync 只从本机到主机:把本地目录里的内容同步进远程目录。远程目录不存在就新建(父目录必须存在),是文件就报错,不能是根目录 /。大小和修改时间都没变的文件、指向不变的链接跳过,摘要里计为「未变」,所以再同步一次只传改过的;其余文件直接覆盖,新文件保留可执行权限。--delete 先删掉远程目录里本地没有的、或类型不同的项(不跟随链接),但不删传输进行中留下的 .filepart 和 .shellrs-….backup,本地读不了的目录也不清理;删不掉的项计为失败。
  • hosts 和 credentials 管理保存的主机和凭据。create、update 从标准输入读一个 JSON 对象(update 只改给出的字段),字段见 shellrs hosts create --help 和 shellrs credentials create --help;show --json 的输出可以改了直接交回 update。校验和对话框一样,报错用对话框的说法:
    • 主机:name、host(地址)、port(默认 22)、user(默认 root)、group(分组路径如 生产/数据库,不存在就逐级新建;同一路径有不止一个分组时报错)、auth(password / credential / no_password)、credential(凭据 ID)、password、route(直接连接、按 ID 列出的跳板主机,或 HTTP / SOCKS5 代理)、notes。跳板只能是保存的主机,不能是自己。改了地址、端口或用户而没给密码时,保存的密码跟着搬过去,同对话框。
    • 凭据:name、kind(password / key / agent)、user、password、key_path(本机私钥文件)或 private_key(私钥全文,同对话框的「粘贴」,存进数据目录的 keys/)、passphrase。凭据的 ID 是 16 位随机串,credentials list 里有。
    • 密码、口令和私钥只写不读:写进系统钥匙串或 keys/,任何命令都不输出,show 只说有没有保存;ShellRS 保存的私钥连路径也不显示。
    • 临时连接和外部连接能 show,不能修改或删除。
    • hosts delete 不确认,连同主机的端口转发规则一起删;主机在 ShellRS 里有打开的标签时拒绝(host_in_use),加 --force 才关掉标签再删。经它跳转的主机,那一跳变成「已删除的主机」。credentials delete 也不确认,用它的主机改为自己登录(同界面)。
    • 改动由 ShellRS 一条一条执行:10 秒内没轮到就撤回、不做;开始执行后会等到完成。
  • 失败时在标准错误输出 shellrs: [错误码] 说明,退出码 255。错误码有 not_running(ShellRS 未运行)、not_enabled(未启用外部 CLI)、host_not_found、credential_not_found、host_key_unknown(还没在 ShellRS 里连过这台主机)、host_key_changed、missing_credential(没有保存密码或口令)、connect_failed、transfer_failed、bad_request、host_in_use、save_failed(改动已做,但没能全部写进数据库或钥匙串)、version_mismatch(命令和正在运行的 ShellRS 版本不同,或 ShellRS 太旧、不认识这个命令),以及 exec --terminal 才有的 no_terminal、terminal_busy、unsupported_shell、too_long。CLI 不弹任何询问:陌生主机、缺少密码都直接失败,请先在 ShellRS 里连接一次。传输完成但有项目失败时退出码为 1。
  • exec --json 从标准输入读 {"host": "<ID>", "command": "<命令>"},命令结束后输出 {"exit_code", "stdout", "stderr"},出错时输出 {"error": {"code", "message"}},退出码和不加 --json 时一样。输出只含 ASCII,中文等字符都转成 \uXXXX;不是 UTF-8 的输出换成 U+FFFD。命令不经过本机 shell 的引号处理,控制台的代码页也不会把输出弄乱,适合 Windows PowerShell 和需要分开读标准输出、标准错误的 Agent。
  • 支持 macOS、Linux 和 Windows。Windows 的 PowerShell 里执行命令优先用 exec --json(@{ host = '<ID>'; command = '…' } | ConvertTo-Json -Compress | shellrs exec --json);要边执行边看输出时(长时间构建、大量日志),改用 here-string 经 --stdin 传入(@'…'@ | shellrs exec <ID> --stdin),并和 list、upload、download 一样,先执行 $OutputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new(),否则中文会变成问号或乱码。命令文本会去掉开头的 BOM、把 CRLF 换成 LF,远程 shell 不会看到多余的回车符。

从堡垒机打开(外部连接)

JumpServer 等堡垒机的本地客户端可以像调用 Xshell 一样调用 ShellRS 打开终端,也可以像调用 WinSCP 一样调用它打开 SFTP:把 ShellRS 设成 SSH 客户端或 SFTP 客户端,参数照 Xshell 或 WinSCP 的写法填。ShellRS 收到 ssh:// 链接就打开一个终端标签连过去,收到 sftp:// 链接就打开一个 SFTP 标签:

ShellRS ssh://用户[:密码]@地址[:端口]
ShellRS -url ssh://用户[:密码]@地址[:端口] -newtab 标签名
ShellRS sftp://用户[:密码]@地址[:端口]
ShellRS /sessionname=标签名 sftp://用户[:密码]@地址[:端口]
  • 认得 Xshell 的 -url(链接)、-newtab(标签名,没给就用地址)和 -newwin(忽略:ShellRS 只有一个窗口),以及 WinSCP 的 /sessionname=标签名(也可以写成 -sessionname=),不分大小写;/newinstance、/ini=nul 等别的选项忽略。只支持 ssh:// 和 sftp://,端口默认 22。用户名和密码里的特殊字符可以按 URL 的规则转义(@ 写成 %40);用户名里本身带 @ 也行,最后一个 @ 后面才是地址。sftp:// 链接里的路径(WinSCP 用它指定打开哪个目录)目前不认,远程一侧照常打开主目录。
  • 标签占满窗口:打开外部连接时,左侧的主机列表自动收起(同 ⌘B),按 ⌘B(其他平台 Ctrl+B)或双击标签即可展开。
  • 外部连接,不保存:不进主机列表、开始页的最近连接和数据库;它的终端和 SFTP 标签都关掉后就没了。标签的菜单里没有「编辑主机…」,其余(在新标签页中连接、打开 SFTP、重新连接)和保存的主机一样。
  • 只用一个通道:很多堡垒机在同一条连接上又开一个通道时会结束整个会话。SFTP 标签本来就只开一个;终端则不探测主机系统(标签上显示名称的首字母),右侧栏只有「命令片段」,历史命令、Docker、系统服务、进程管理、网络连接和系统监控都要另开通道执行命令,这里不提供。
  • 链接里的密码只留在内存里,不进钥匙串,重新连接时照样用它;没带密码时,服务器要密码就弹框问。第一次连到某台堡垒机要信任它的主机密钥,记在 ShellRS 自己的 known_hosts 里,下次不再问。
  • ShellRS 已经在运行时,链接交给正在运行的那个打开,窗口调到前面,不会再起一个 ShellRS。链接有问题(不是 ssh:// 或 sftp://、没有用户名或地址、端口不对)时,ShellRS 弹通知说明原因。
  • 堡垒机要调用的程序:
    • Windows:安装目录里的 shellrs.exe(默认 %LOCALAPPDATA%\Programs\ShellRS\shellrs.exe)。不要用 PATH 里的 shellrs.exe:那是外部 CLI 的副本。
    • macOS:/Applications/ShellRS.app/Contents/MacOS/shellrs。不要用 open -a ShellRS --args …:ShellRS 已在运行时,系统会把参数丢掉。
    • Linux:AppImage 本身。
  • 外部 CLI 的 shellrs hosts list 也列出外部连接(JSON 里 "temporary": true,表格的分组一栏写「(未保存)」),标签开着时 Agent 可以用它的 ID 执行命令、传输文件,这期间 ID 不变,可以一直用。标签关掉后 ID 失效;堡垒机再拉起一次(即使是同一台资产)是新的外部连接,ID 也是新的。和保存的主机一样,每条命令都用链接里的用户名和密码重新登录一次;堡垒机给的若是只能用一次的令牌,这次登录会被拒绝,这时改用 shellrs exec --terminal,在外部连接已打开的终端里执行命令(见「外部 CLI」)。
  • 命令行参数里的密码在本机的进程列表里看得到,这是堡垒机这样传参本身的问题。

标签页

远程终端标签和 SFTP 标签都以主机系统徽章为图标(与主机列表相同)。右键标签可重命名(仅本次运行有效,留空恢复为主机的名称,用于区分同一台主机的多个连接)、在新标签页中连接、打开 SFTP、复制 IP 地址 / 主机名、重新连接、编辑主机,以及关闭当前、左侧、右侧、其他或全部标签。SFTP 标签的菜单是「重命名标签…」(留空恢复为「主机的名称 · SFTP」)、打开 SFTP、复制 IP 地址 / 主机名、重新连接加关闭命令,标签栏右侧和远程终端一样有「SFTP」和「重新连接」按钮;本地终端标签是「重新启动」加关闭命令。标签栏右侧「…」按钮的菜单与当前标签的右键菜单相同。双击任一标签的标题可隐藏或显示左侧的侧栏(同 ⌘B 和标题栏的按钮)。远程终端运行时和 SFTP 标签已连接时,标签栏右侧显示这条 SSH 连接的往返延迟,每 5 秒更新一次:低于 100 ms 为绿色,100–200 ms 为黄色,高于 200 ms 或超时为红色。SFTP 传输进行中也照常测量,读数会随传输占满带宽而升高。批量关闭时,正在上传的 SFTP 标签仍会先确认。

终端

右键终端内容区可复制、粘贴、查找、清屏;远程终端另有打开 SFTP、重新连接和断开连接。断开连接只断开这一个标签,标签保留,可随时重新连接,同一台主机的其他标签和 SFTP 不受影响。

  • 查找(⌘F,其他平台 Ctrl+Shift+F):在终端右上角打开查找条,按字面量搜索屏幕和回滚历史。查询全为小写时不区分大小写,含大写字母时区分。所有匹配高亮显示,当前项颜色更深,查找条显示「当前项/总数」。回车或 ⌘G(F3)跳到下一项(更新的输出),Shift+回车或 ⌘⇧G(Shift+F3)跳到上一项(更早的输出),到头后循环。Esc 关闭。打开时如有选中文字,会作为查询词。
  • 清屏(⌘K,其他平台 Ctrl+Shift+K;焦点不在终端时 ⌘K 仍是聚焦侧栏的搜索框):清掉屏幕和回滚历史,只留下光标所在的提示符行,包括已输入但未回车的内容。清屏只在本地进行,不向服务器发送任何内容。vim、top 等全屏程序运行时不可用。
  • 链接:输出里的 http://、https:// 地址,以及程序明确标出的链接(如 ls --hyperlink、gcc 的报错),显示为带下划线的蓝色。按住 ⌘(其他平台 Ctrl)单击,用系统浏览器打开;不按时单击照旧是选择文字。鼠标在链接上停一会儿会显示它真正的地址:程序标出的链接,显示的文字可以和地址不同。地址末尾的句号、逗号和不成对的右括号不算在内;被折成两行的长地址仍是一个链接。其他协议(如 file://)不当作链接。
  • 鼠标:vim(:set mouse=a)、htop、tmux(set -g mouse on)、mc 这类程序要求鼠标时,单击、拖动和滚轮都交给程序。按住 Shift 拖动仍是选择文字,按住 Shift 滚动仍是翻看回滚历史;右键始终是 ShellRS 的菜单。
  • 通知:程序可以请求通知(OSC 9,或 OSC 777 的 notify;标题;正文),终端响铃时也会提醒。ShellRS 不在前台时发系统通知(macOS 第一次会询问是否允许),点通知回到那个终端;ShellRS 在前台但终端在别的标签时,在窗口右上角提示,点一下切过去。程序请求的通知即使终端就在眼前也会提示;响铃只在看不见那个终端时提醒(Tab 补全等也会响铃)。通知标题是标签名,看得出是哪台主机发的。同一终端的程序通知 2 秒内、响铃 10 秒内只提醒一次。设置 › 终端 › 通知可以分别关掉。命令跑完想被提醒,可以在后面加上 ; printf '\e]9;完成\a' 或 ; tput bel;Claude Code 等命令行工具需要你处理时也会这样提醒。
  • 关键字高亮:设置 › 关键字高亮 里的规则把匹配的文字按规则的颜色显示在所有终端里,回滚历史里的也一样。只改显示:服务器的输出不变,复制出的文字也不变;窗口缩放、长行折行后照样匹配,被折成两行的词两段都上色。这个功能默认关闭,打开页面上方的「启用关键字高亮」后才生效,关掉它就一次停用全部规则;「预览」用当前终端的字体和配色显示一段示例输出,规则改动立即反映在预览和已打开的终端里。规则表一行一条,直接在表里改:「启用」、「正则表达式」(区分大小写,开头加 (?i) 不区分)、「备注」、颜色(点色块用取色器,或在旁边填 #rrggbb)、「通知」,行尾的垃圾桶删除这一条。正则写错时在框下方提示,这条规则暂不生效。规则从上到下应用,重叠处前面的规则优先;按住行首的把手拖动可调整顺序。初始有三条示例:ERROR 红色、WARN 琥珀色、IPv4 地址蓝色,都已启用、不通知,打开总开关就能看到效果,可以修改或删除。勾选「通知」的规则在看不到那个终端时提醒,和响铃一样:ShellRS 不在前台时发系统通知,终端在别的标签时在窗口右上角提示;标题是「标签名:备注」(没填备注时用正则),正文是匹配的那一行。只检查换了行的新输出,同一终端 10 秒内只提醒一次,反复重画的同一行 5 分钟内只提醒一次。vim、less、top、tmux 这类全屏程序里不高亮,也不提醒。尚未实现:按主机区分规则、加粗等文字样式、用键盘调整顺序。
  • 远程复制:远程程序用 OSC 52 复制的内容(如 tmux 的 set -g set-clipboard on、vim 的 OSC 52 插件)直接进本机剪贴板。远程程序读不了本机剪贴板。

右侧栏

当前标签是远程终端时,窗口最右边有一列工具按钮:命令片段、历史命令、Docker、系统服务、进程管理、网络连接、系统监控。点一个就在右侧打开这个工具,再点一次收起;⌘⌥B(其他平台 Ctrl+Alt+B)显示或隐藏右侧栏。拖动右侧栏的左边缘可以加宽,最窄就是打开时的宽度。右侧栏只跟着远程终端出现,切到 SFTP、本地终端或设置时连同按钮一起隐藏,回到任一远程终端时按原样恢复,内容对应当前这个终端的主机。把标签拖成分屏后,右侧栏不隐藏:它对应最近一次切到或点进去的远程终端,点进另一半的 SFTP 或本地终端时不变,屏幕上一个远程终端都没有时才隐藏;标题里写着它对应哪台主机(如「系统监控 · web-01」),状态栏也跟着点进去的那一半。已知不是 Linux 的主机(macOS、Windows、BSD)不显示系统服务、进程管理、网络连接和系统监控的图标;历史命令和 Docker 除了 Windows 主机都有(Mac 上装了 Docker Desktop 也能用)。

命令片段保存常用的命令,所有主机共用。点顶部的加号新建片段:名称、分类和命令,命令可以有多行。片段按分类分组显示,没有分类的放在最后的「未分类」下;点分类标题折叠或展开,右键分类标题可以在这个分类里新建片段、重命名或删除分类(分类里的片段会一起删除,确认时写明个数);顶部的文件夹按钮新建分类。可以按名称或命令搜索,输入几个词时列出同时包含这些词的片段。

点一个片段就在终端里执行它的命令(片段默认「点击时自动执行」)。鼠标移到片段上时,右边会显示点它会怎样:闪电表示点击就执行,▶ 表示点击只输入。在片段对话框里取消勾选「点击时自动执行」,点它就只把命令放进终端的输入行(替换掉已经输入的内容),可以修改后回车。点右边的闪电或 ▶ 总是直接执行;右键还可以输入到终端、复制命令、编辑和删除。终端里正在运行 vim、less 这类全屏程序时不会输入。Windows 主机上不会替换已经输入的内容,命令接在后面输入。

历史命令列出远程主机上 bash 的历史命令(~/.bash_history),最近执行的在最前,同一条命令只列一次,下面写着执行过几次;bash 记录了时间(设置了 HISTTIMEFORMAT)时还写明最近一次是什么时候,多行的命令也能认出来。可以搜索,输入几个词时列出同时包含这些词的命令,不分大小写。点一条命令把它放进终端的输入行(替换掉已经输入的内容,不执行),可以修改后回车;点右边的执行按钮直接执行;右键还可以复制。终端里正在运行 vim、less 这类全屏程序时不会输入。

bash 在 shell 退出时才把这次执行的命令写进历史文件,所以当前终端里刚执行的命令要等它退出后才会出现。列表在打开历史命令或切换终端时读取,之后点刷新按钮才重新读取;历史文件很长时只读最后 512 KB。

Docker 顶部是 Docker 和 Compose 的版本,下面「容器」「卷」「镜像」「网络」四个标签页带数量。「容器」页里,同一个 compose 项目的容器归在项目卡片下(项目名、运行中 / 总数、项目目录),点项目那一行折叠或展开,只有一个容器、而且它在运行的项目默认展开,有多个容器的项目默认折叠;不属于任何项目的在「独立容器」下。每个项目和容器右边有「停止」(或「启动」)和「重启」,项目的按钮作用于它所有的容器;点容器或它的「…」打开详情:「详情」页是名称、ID、镜像、创建时间、入口、命令、端口映射、挂载、环境变量和标签,「日志」页是容器最近 200 行输出;底部可以启动、停止、重启,已停止的容器还可以删除。「卷」「镜像」「网络」页列出各自的名称和基本信息,标出是否有容器在用;没有容器在用的可以点右边的删除按钮删除(Docker 自带的 bridge、host、none 网络不能删)。点卡片打开详情:卷是驱动、挂载点、创建时间、使用它的容器、选项和标签;镜像是完整 ID、标签、摘要、创建时间、大小、平台、层数、使用它的容器、运行配置(入口、命令、工作目录、用户、暴露端口)、环境变量和标签;网络是驱动、范围、IPv6、子网和网关、连在上面的容器及其地址、选项和标签。详情底部也可以删除。

停止、重启和删除都会先确认,启动直接执行,结果以通知显示,之后列表重新读取。不是以 root 登录、也不在 docker 组里时,通过免密码的 sudo 执行。列表在打开 Docker 或切换终端时读取,之后点刷新按钮才重新读取。主机没有安装 Docker 或 Docker 没有运行时会写明。

系统服务列出远程主机上的 systemd 服务(不含模板),分成「自定义服务」(unit 文件在 /etc/systemd/system,也就是管理员自己加的)和「系统服务」两组。顶部是 systemd 版本和整机状态(有服务失败时是「降级运行」);「全部」「运行中」「已停止」「失败」四个标签页带数量,也可以按服务名或描述搜索。每个服务一张卡片:状态圆点、名称、描述、运行状态和开机启动状态;运行中的服务右边有「停止」「重启」,没运行的有「启动」,点「…」或卡片打开详情。详情的「状态」页是加载状态、运行状态、开机启动、主进程 PID、内存、任务数、重启次数、退出状态、启动和停止时间、unit 文件;「日志」页是这个服务在 journal 里最近 200 行。详情底部和右键菜单里同样可以启动、停止、重启,以及启用或禁用开机启动。

停止和重启会先确认(停止 SSH 服务时会特别说明),启动和开机启动的设置直接执行,结果以通知显示,之后列表重新读取。这些操作需要 root 权限:不是以 root 登录时通过免密码的 sudo 执行,sudo 需要密码时会提示需要 root 权限。列表在打开系统服务或切换终端时读取,之后点刷新按钮才重新读取。没有使用 systemd 的主机会写明暂不支持。

进程管理列出远程 Linux 主机上的进程(不含内核线程),每个一张卡片:状态圆点(绿色运行中、灰色休眠、黄色等待 I/O 或已暂停、红色僵尸进程,鼠标停上去显示状态)、进程名、PID、用户、启动时间(按本机时区),以及内存用量和占物理内存的比例、CPU 占用。CPU 占用和 top 的算法一样,按一个核计:占满两个核是 200%;它要两次读数才算得出,所以刚打开时先显示「—」,2 秒后出现。默认按内存从多到少排列,点「CPU」改按 CPU 排列,再点一次同一个按钮反过来排;可以按进程名、PID 或用户搜索,右边的数字是当前列出的个数。每 15 秒刷新一次,只在进程管理显示时读取,点右上角的刷新按钮立即读取。

点一个进程打开它的详情:PID、父进程、用户、状态(括号里是 ps 的状态字母,如 Ssl)、启动时间、运行时长、终端、优先级、Nice、CPU 使用率、累计 CPU 时间、常驻内存、虚拟内存、线程数、直接子进程数和全部后代进程数,下面是完整的命令行(打开详情时读取,可「复制命令」)。底部有「复制 PID」「结束进程」「强制结束」。

右键一个进程可以「查看详情」「结束进程…」(发送 SIGTERM,进程可以先做完收尾再退出)或「强制结束进程…」(发送 SIGKILL,立即终止);从详情里结束也一样,都会先确认。结果以通知显示,1 秒后列表重新读取。不是以 root 登录时只能结束自己的进程。进程超过 2500 个时只列出前 2500 个,列表顶部会写明。

网络连接列出远程 Linux 主机上所有的 TCP、UDP 连接和监听端口,每条一张卡片:协议、状态、本地和远端地址,占用它的进程和 PID,以及所属用户。右上角写明这是「监听端口」「入站连接」(连到本机监听的端口)还是「出站连接」。顶部是总数、监听端口数和已连接数;可以按地址、端口、状态、PID、进程名或用户搜索,也可以按协议和状态筛选。监听的排在最前,然后是已连接的,TIME_WAIT 等正在关闭的排在最后;同一个端口被多个进程共同监听(如 nginx 的多个 worker)时合成一张卡片。

列表在打开网络连接或切换终端时读取一次,之后不会自己变化,点右上角的刷新按钮重新读取。数据通过这个终端已有的 SSH 连接读取,不需要再次登录,用的是主机上的 ss 命令;没有 ss 的主机(如 BusyBox)改为读取 /proc/net,这时看不到进程;不是以 root 登录时只能看到自己的进程。这两种情况列表顶部都会写明。连接超过 3000 条时只列出前 3000 条(监听端口总在其中),总数仍然准确。

系统监控显示远程 Linux 主机的:

  • 系统:主机名、架构、发行版、运行时长(如「32 天 23:40:26」)。
  • CPU:型号、核数和平均使用率;多核时下面每核一根小竖条,鼠标停在竖条上显示这个核的编号和使用率。默认只显示一行,核多到一行放不下时点右上角的「N 核」展开全部。
  • 内存:物理内存的使用率和用量;有交换空间时另有一行。
  • 网络:主网卡(默认路由所在的网卡)的上传、下载速率;有多块网卡时点右上角的「N 个网卡」展开全部(不列回环网卡和从没收发过数据的网卡)。
  • 磁盘:每个本地挂载点的占用(不含 tmpfs 等内存文件系统和系统目录下的挂载)。

数据通过这个终端已有的 SSH 连接读取,不需要再次登录,也不安装任何东西;每 2 秒刷新一次(磁盘每 30 秒一次),只在系统监控显示时读取。每次刷新只读取几个系统文件,除了执行它的 shell 不在服务器上启动其他进程。使用率达到 70% 显示为黄色,达到 90% 显示为红色。终端未连接时显示提示;还没识别出系统的主机如果不是 Linux,会写明暂不支持。

SFTP

打开主机的「SFTP」标签即可浏览本地与远程目录;和终端一样,每次「打开 SFTP」都新开一个标签,同一台主机可以开多个,各自独立连接、各看各的目录。操作方式对标 WinSCP Commander。SFTP 使用独立 SSH 连接,仅请求 SFTP 子系统,不要求服务器提供 Shell;关闭终端不会中止传输。

工具栏

每一侧面板都有两行工具栏,下方是路径标签。面板太窄放不下时,按钮从右往左整个隐藏,不会换行(对应的命令在右键菜单和快捷键里仍然可用)。新开的 SFTP 标签本地、远程两侧各占一半;两侧和队列之间的分隔线拖到哪里,在这个标签关闭之前都会记住,切到别的标签再回来也不变:

  • 第一行(导航):
    • 「目录列表」:列出从根到当前目录的每一级,本地另有主目录、桌面、文稿、下载,选中即前往。
    • 书签:点按钮打开「打开目录/书签」(见下);旁边的下拉箭头列出这台主机这一侧的书签,点击即前往,也可添加或移除当前路径。书签保存在本地数据库,删除主机时一并删除。
    • 上级目录、根目录、主目录、刷新、后退、前进。
    • 显示 / 不显示隐藏文件:名称以 . 开头的文件和目录。睁开的眼睛表示正在显示,划掉的眼睛表示不显示。本地和远程各自一个开关,互不影响;每一侧的选择对所有 SFTP 标签生效,保存在设置里,默认都不显示。不显示时面板底部写明「隐藏 N 项」;显示时隐藏文件的文字颜色浅一些。
  • 第二行(文件):
    • 远程是「下载…」,本地是「上传…」,下拉里还有「选择文件上传…」。
    • 删除、重命名…、属性…、新建(文件夹… / 文件…)。

路径标签

与 WinSCP 的路径标签相同:

  • 显示当前目录的完整路径,例如 /home/tester/。
  • 每一级都可以点:悬停时从根到该级高亮,单击即前往。
  • 路径放不下时保留根目录和末尾几级,中间折成 …,点 … 前往被折叠的最后一级。
  • 单击当前目录、双击路径右侧空白处打开「打开目录/书签」。
  • 右键:前往、刷新、添加路径到书签、复制路径、打开目录/书签…。

打开目录/书签

与 WinSCP 的「打开目录」对话框相同,可以从路径标签、书签按钮、⌘O(其他平台 Ctrl+O;macOS 另有 ⌘⇧G)或路径标签的右键菜单打开:

  • 「目录」预填当前目录并已选中,直接输入即可替换。~ 表示主目录,相对路径从当前目录算起。本地侧另有「浏览…」。
  • 下方是这台主机这一侧的书签。与目录相同的书签处于选中状态;单击书签把它填入目录,双击直接打开。
  • 「添加」把目录加入书签,「删除」(或在列表中按 Delete)删除选中的书签并选中相邻的一个,「上移」「下移」调整顺序。
  • 书签的改动立即保存,按「取消」也不会撤销,与 WinSCP 相同。
  • 回车或「打开」前往目录;Esc 或「取消」关闭。

列表下方的状态栏平时显示项目数和已选数量;连接中和读取目录超过 0.3 秒时显示「正在连接 SFTP…」或「正在读取目录…」。读不了目录或连接断开时,原因用红字显示在窗口最左下角(平时显示「已连接 主机的名称」的位置);空闲时断网也会自己发现,不用等到刷新,时机和同一台主机的终端一样;重新连接用标签栏的「重新连接」按钮或标签菜单;断开时在远程列表里做任何操作(刷新、打开目录、删除、上传下载等)会弹出「SFTP 连接已断开」对话框,说明原因,并可直接「重新连接」。这些都不会让列表移动。

列与 WinSCP 相同:本地为名称、大小、类型、修改时间,远程为名称、大小、修改时间、权限、所有者。

  • 大小默认以 KB 显示(4,008,960 KB,向上取整,只有空文件是 0 KB),与 WinSCP 相同。右键「大小」列标题可切换为「字节」(4,105,175,040 B)、「千字节(KB)」或「简短格式」(按大小用 B、KB、MB、GB,如 3.8 GB),对所有 SFTP 标签生效并保存在设置里。按大小排序始终按实际字节数。
  • 时间形如 2026/4/22 12:44:53。
  • 权限形如 rwxr-xr-x。
  • 所有者来自服务器的 ls -l 行。
  • 链接到目录的符号链接显示为带箭头的文件夹,可以双击进入。

选择与右键菜单

  • 与 WinSCP 关闭「整行选择」时相同,「名称」格才是项目:鼠标移上去时只有名称格变灰,单击、双击、右键都作用在名称格上,选中时整个名称格高亮;行里的其他列和列表下方都算空白处。
  • 鼠标:单击名称格选中(其他选择取消),⌘ 单击(其他平台 Ctrl 单击)增减,Shift 单击选取范围,双击打开。单击空白处取消全部选择(按住 ⌘ 或 Shift 时不取消)。
  • 框选:在名称右边的空白、大小、类型、时间等列或列表下方按下拖动,画出选框,框住的行被选中;按住 ⌘ 或 Shift 开始拖动则加到已有选择上。拖到列表上下边缘时自动滚动。拖动文件名才是把文件拖到另一侧传输:按下未选中的文件名时只选中它(其他选择取消),拖走的就是它一个;按下已选中的文件名则拖走全部已选。拖动时只有到了另一侧列表上才显示「上传 / 下载 N 个项目」,在自己的列表或其他不能放下的地方,指针显示为禁止。
  • 键盘:↑↓、Home、End、PageUp、PageDown 移动,加 Shift 扩展;空格或 Insert 切换当前行;⌘A 全选;Tab 切到另一侧。
  • 右键未选中的名称格会先选中它;右键空白处取消选择并弹出空白处菜单。
    • 文件名上的菜单:编辑(文件;图片、SVG 和 Markdown 另有预览,SVG 以外的图片只有预览)、上传… / 下载…、复制路径(选中项目的完整路径,多个时每行一个)、删除、重命名…、属性…。目录双击进入,菜单里没有「打开」。
    • 空白处的菜单:前往(上级 / 根 / 主目录 / 后退 / 前进)、刷新、显示隐藏文件(勾选表示这一侧显示)、添加路径到书签、新建。

快捷键

命令 快捷键
上传 / 下载(按所在面板) F5
重命名 F2
新建文件夹 F7
删除 F8、Delete;macOS 另有 ⌘⌫
属性 F9;macOS 另有 ⌘I
编辑文件 F4
刷新 ⌘R / Ctrl+R
上级目录 Backspace;macOS 另有 ⌘↑
根目录 ⌘\ / Ctrl+\
主目录 macOS ⌘⇧H,其他平台 Ctrl+H
后退 / 前进 ⌥← / ⌥→;macOS 另有 ⌘[ / ⌘]
添加路径到书签 ⌘D / Ctrl+D
打开目录 / 编辑文件 Enter;macOS 另有 ⌘↓
打开目录/书签 ⌘O / Ctrl+O;macOS 另有 ⌘⇧G
显示 / 不显示隐藏文件(按所在面板) macOS ⌘⇧.,其他平台 Ctrl+Alt+H

文件操作

  • 删除前会确认,并写明对象和后果:
    • 本地项目移到废纸篓。
    • 远程项目永久删除,目录连同其中全部内容。
    • 删除符号链接只删除链接本身。
  • 重命名和新建:
    • 按当前列表检查名称;不能为空,不能是 . 或 ..,不能与已有项目同名。
    • 重命名不会覆盖已有项目。
  • 属性:
    • 显示位置、大小、修改时间,远程另有所有者和组。
    • 权限用 3×3 复选框和八进制数字编辑,两者同步。
    • 多选时,项目之间不一致的权限位保持原样,除非你改动它。
    • 含目录时可以递归应用;递归时默认「为目录添加执行权限(X)」,避免目录无法进入。
    • 符号链接不参与修改权限。

编辑文件

文本文件可以直接在 ShellRS 里改,远程和本地的都行(与 WinSCP 的内置编辑器相同):

  • 打开:双击文件、选中后回车或按 F4、右键「编辑」。「新建 › 文件…」建好后也直接打开。文件在中间区的「编辑器」标签里打开,和终端、SFTP 一样可以拖成分栏;同一个文件只开一个标签,再打开就切到它。
  • 编辑器有行号、查找替换(⌘F / Ctrl+F,替换 ⌘⇧F / Ctrl+H),按文件名为 Shell、YAML、TOML、JSON、Python、JavaScript、HTML、CSS、Markdown、SQL、PHP、Go、Lua、Makefile、Diff 着色,其他文件是纯文本。Makefile 和用 Tab 缩进的文件按 Tab 输入制表符。
  • 保存:⌘S / Ctrl+S 或标签上方的「保存」。远程文件经打开它的 SFTP 标签的连接直接写回原文件(原地改写),所有者、权限和指向它的链接都不变。保存前会核对文件的大小和修改时间:打开后被别人改过或删掉了,会先问是否「覆盖」,不会悄悄覆盖。写到一半连接断开时,服务器上的文件可能只写了一部分,编辑器里的内容还在,重新连接后再保存一次即可。
  • 「重新加载」从服务器或磁盘重新读一遍;有没保存的修改时先确认。
  • 标签上的圆点表示有没保存的修改。关闭这样的标签会问「保存」「放弃修改」还是「取消」;一次关闭多个标签、关闭 SFTP 标签(它打开的远程文件会一起关掉)或退出 ShellRS 时,有没保存的文件会先问一次。macOS 上从程序坞退出和注销关机不会询问。
  • 窗口左下角是这个文件所走的 SFTP 连接(本地文件写「本机文件」),右下角是光标位置和编码、换行方式(如「UTF-8 · LF」)。
  • 限制:只打开 5 MB 以内的 UTF-8 文本文件(带不带 BOM 都可以,保存时原样保留 BOM 和 CRLF 换行)。更大的文件、二进制文件和 GBK 等其他编码的文件会说明原因、不打开,远程文件可以改用「下载…」。

预览

图片(PNG、JPG、GIF、WebP、SVG、BMP、ICO、TIFF)和 Markdown 可以预览,远程和本地的都行:

  • 打开:双击图片;Markdown 和 SVG 是文本,双击是编辑,预览用右键「预览」。
  • 预览是一个占窗口大部分的对话框,Esc、右上角的关闭或「关闭」按钮关掉。Markdown 排版后显示,可以滚动、选中复制,点链接用浏览器打开。
  • 图片默认「适合窗口」:按原比例缩小到放得下(小图不放大),居中显示;上方写像素尺寸、文件大小和当前比例。放大、缩小按钮(或 ⌘= / ⌘-,其他平台 Ctrl)按 10%–800% 的档位缩放,按住 ⌘(Ctrl)滚动滚轮或触控板可以连续缩放;「原图」(⌘0)按一个图片像素一个点显示,「适合窗口」(⌘9)回到放得下的大小;双击图片在两者之间切换。图片比预览区大时可以上下左右滚动查看,缩放时画面中间的位置保持不动。
  • 下方的「下载…」把远程文件下载到本机(打开下载确认框),Markdown 的「编辑」打开编辑器(已打开就切过去)。
  • 预览的是服务器或磁盘上的文件,编辑器里没保存的修改不会出现在预览里。
  • 限制:图片 20 MB 以内,Markdown 5 MB 以内且是 UTF-8;更大的会说明原因,远程文件可以改用「下载…」。

上传与下载

  • 入口:
    • 上传:「上传…」、本地列表中的 F5、「选择文件上传…」,或按住本地项目的文件名拖到远程列表,或把 Finder 中的文件拖到远程列表。
    • 下载:「下载…」、远程列表中的 F5,或按住远程项目的文件名拖到本地列表。
    • 拖到目录行时放进该目录,拖到其余区域时放进当前目录。
  • 所有入口都显示确认框,可以修改目标目录;下载可以用「浏览…」选择本机目录。确认框写明数量和种类(如「上传 2 个文件到 …」),来源的所在目录只写一次,每个项目占一行,悬停可看完整路径。
  • 确认后来源、端点和目标即固定。每个 SFTP 标签同时运行一个批次(上传和下载共用),批内依次处理;传输进行中还可以继续上传或下载,新的批次排进传输队列,前一批结束后自动开始。其他 SFTP 标签、主机和终端可以继续操作。
  • 递归传输包含空目录。符号链接原样创建,不跟随。默认二进制传输,保留普通文件的修改时间。
  • 新建项使用目标一侧的默认权限,覆盖时保留目标原有的基本权限。不复制所有者、ACL 或扩展属性。
  • 同名目录合并。文件或链接冲突时询问覆盖、跳过或取消,可以应用于本批剩余冲突;目录与非目录冲突不会自动删除。
  • 出错时可以重试、跳过或取消,完成后的汇总分别列出成功、跳过和失败。

传输队列

与 WinSCP 的队列面板相同,有传输时出现在双栏下方,高度可拖动,清除全部已结束的批次后收起。

  • 每一批一行:操作(上传 / 下载)、来源(一个项目时是它的路径,多个项目时是所在目录)、目标、已传输(单位与「大小」列相同)、时间(剩余时间)、速度(最近几秒)和进度。
  • 进行中的批次显示总进度条,下面一行是正在传的文件和它自己的进度条,对应 WinSCP 进度对话框里的两个进度条。
  • 进度列:等待中、正在扫描、百分比、等待回答、重连说明、已停止、已完成、部分失败(N 项)、已移出。
  • 点行首的箭头展开这一批的逐项结果(完成、已跳过、失败及原因),最新的在最上面。
  • 工具栏:继续(停止的批次)、停止(进行中的批次)、移出队列(选中的排队中或已结束的批次,或停止的批次)、丢弃续传进度、清除已完成。
  • 停止的批次留在队首,等你继续、丢弃续传进度或移出队列之后,后面的批次才会开始;移出队列不删除续传记录,下次传同样的文件仍会询问是否续传。
  • 队列只在本次运行中保留,关闭 SFTP 标签时一起清除;有未完成的批次时关闭标签会先确认。

断点续传和替换

文件先写入 <目标文件名>.filepart。写入请求采用有界流水线,收到每个写入确认并关闭成功后才发布正式文件;服务器支持时先调用 fsync@openssh.com。支持 posix-rename@openssh.com 的服务器使用原子替换;其他服务器先将旧文件移到 .shellrs-<UUID>.backup,再发布新文件,此兼容路径不保证原子性。发布响应丢失时根据受管理临时路径、阶段、类型和大小恢复,无法安全判断则保留恢复文件并报告。

续传记录保存在应用数据目录的 upload-resume/,采用版本化 JSON 和原子写入,不写入密码、口令或私钥,不改变数据库结构。记录用于绑定端点、主机指纹、来源、目标和安全替换阶段。续传方式与 WinSCP 相同:读取远端 .filepart 的当前大小,在本地文件中跳过相同长度并继续传输;使用者需确保来源仍是同一版本。上传过程不会为了校验而回读远端文件内容。

下载同样先写入本机的 <目标文件名>.filepart,完成后设置远程的修改时间、fsync,再在同一文件系统内重命名为正式文件(原子替换)。并发的读取请求可能乱序、短读返回,但临时文件严格按顺序写入,因为续传只信它的长度。下载续传记录保存在 download-resume/,绑定端点、主机指纹、远程来源及其大小与修改时间、本地目标;远程文件变化后不能续传,只能重新下载或跳过。

网络故障每批最多自动重连三次,间隔 1、3、10 秒。耗尽后使用「继续上传」或「继续下载」,手动恢复会重置次数。认证失败、主机密钥变化和主动取消需要用户处理。重连沿用原连接配置,编辑主机不会改变正在传输的目标。

取消、关闭标签、断开连接或退出时保留续传记录;关闭正在传输的标签会先确认。重启后不会自动继续,再次选择相同来源和目标时会询问续传。停止状态下可使用「丢弃续传进度」清理该批受管理的临时文件;存在无法判断的恢复备份时会保留文件并说明原因。成功发布的项目自动清理记录和备份。

文件名不能准确表示时会明确报错。当前 russh-sftp 3.0.0 的远端字符串解码会替换无效 UTF-8,浏览器因此拒绝包含替换字符 U+FFFD 的远端名称,避免访问错误路径。符号链接沿用 OpenSSH 的 SFTP v3 参数顺序。

尚未实现:SFTP 标签里的目录同步(外部 CLI 的 shellrs sync 可以同步)、前台传输进度对话框、队列排序、过滤、查找文件、目录树和 Dock 布局持久化。

下载与更新

安装包在 GitHub Releases:

系统 首次安装 自动更新
macOS(Apple Silicon 和 Intel 共用一个包) DMG,把 ShellRS 拖进「应用程序」 支持
Windows x64 安装程序,按当前用户安装到 %LOCALAPPDATA%\Programs\ShellRS,不需要管理员 支持
Linux x64 AppImage 支持

ShellRS 启动 30 秒后检查一次有没有新版本,之后每 6 小时检查一次。有新版本就在后台下载并校验,完成后标题栏右上角出现绿色的更新按钮。点开后,「查看更新内容」打开官网的更新日志,「重启并安装」换成新版本并重新打开。重启会断开已打开的连接、停止传输(续传进度保留)和端口转发,对话框里会写明具体有哪些。

「设置 › 关于」里的「应用更新」只有三行:

  • 当前版本:下面写着现在的状态(已是最新、正在下载、已下载等),右边是版本号和一个按钮:平时是「检查更新」,下载好之后变成「重启并安装…」。构建号和平台在版本号的悬停提示里。

  • 更新渠道:稳定版适合日常使用;Beta 可以提前收到测试版本,稳定版发布时也会收到。切换后马上按新渠道检查(关掉自动升级时等你手动检查)。

  • 自动升级:关掉之后只在手动检查时才联网,发现新版本时由你决定是否下载。

  • 校验:更新清单由 ShellRS 的发布密钥签名,安装包按清单里的大小和 SHA-256 核对,任何一步对不上都不会安装。macOS 上还会核对新版本的开发者签名。

  • 隐私:检查更新只发送 ShellRS 的版本号、操作系统和 CPU 架构,不发送任何能识别这台电脑或用户的信息。匿名使用统计见「隐私」一节。

  • 不能自动更新的情况:从 DMG 里直接运行、没有放进「应用程序」文件夹、对安装位置没有写权限、Linux 上不是用 AppImage 运行,或者是自己编译的开发构建。这时「关于」页会说明原因,有新版本时给出「前往下载页」。

  • 退回旧版本:数据库在升级到新结构之前会备份成 shellrs.db.v<旧版本>.bak。旧版本打开新结构的数据库时会拒绝打开,以免把新版本保存的数据弄乱;需要退回时,把备份改名回 shellrs.db。

隐私

ShellRS 不发送主机、凭据、会话内容、命令、文件名或路径,也不发送任何能识别这台电脑或用户的标识。联网的只有这两件事(连接主机本身除外):

  • 检查更新:只发送 ShellRS 的版本号、操作系统和 CPU 架构,见「下载与更新」。
  • 匿名使用统计:发给 Aptabase,用来了解安装量、每天有多少台设备在用、各版本的分布,以及哪些功能用得多。「设置 › 关于 › 隐私」里的「发送匿名使用统计」默认打开;关掉后不再发送,本机攒下的计数也一并清除。

每个统计事件都带 ShellRS 的版本号、操作系统的名称和版本(如 macOS 15.1、Windows 10.0.22631、Ubuntu 24.04)。事件只有四种:

事件 什么时候发
app_installed 第一次启动时发一次。数据目录里记着已经报过,换一个数据目录或删掉它会再报
app_started 每次启动
app_active 当天(UTC)第一次把窗口切到前台时;启动当天不再重复。macOS 上关了窗口、留在后台不算
usage 各功能的使用次数:从第一次使用算起满 4 小时,在下一次启动、切到前台或使用时汇总成一条

前三种附带这些设置和数量,取值都是固定的几种:CPU 架构、应用外观、界面语言、浅色和深色主题(内置主题的名字)、界面是否跟随主题、关键字高亮、外部 CLI 和自动升级是否打开、更新渠道、是否改过快捷键,以及保存的主机、凭据、端口转发、命令片段各有多少(只报档位:0、1-5、6-20、21-100、100+)。

usage 只有次数,没有内容,计的是:SSH 终端连上(另按跳板、代理、凭据、无密码、临时连接、外部连接分别计数)、SFTP 连上(另按临时连接、外部连接计数)、本地终端、端口转发开启(本地、远程、动态)、上传和下载批次、编辑器打开本地和远程文件、预览图片和 Markdown、打开右侧栏的七个工具、命令片段和历史命令送进终端、终端查找、通知(程序、响铃、关键字),外部 CLI 的 exec、exec --terminal、upload、download、sync、hosts、credentials 命令,以及打开和关闭关键字高亮、外部 CLI。

  • 计数先存在数据目录的 analytics.json 里,退出不会丢,之后再补发。离线或在内网里不影响使用:发不出去时等 1 分钟,之后每次加倍、最长 6 小时再试,而且只在使用 ShellRS 时顺带重试,空闲时不发任何请求。
  • Aptabase 按请求的 IP 地址推断国家和地区,但不保存 IP。它区分设备用的是 IP 和 User-Agent 加上每天更换的随机盐算出的散列,所以看不到同一台设备跨天的行为。
  • 自己编译的开发构建不发送统计;外部 CLI(shellrs 命令)本身也不发送。