‹ 指南

连上了,但 mosh-server 找不到? v26.1.0+

登录成功了,mosh-server 却没启动。几乎总是 PATH 的问题,这里讲怎么找到它,以及让主机指向它。

需要 Term v26.1.0 或更高版本。

撰写于

这条错误在说什么

mosh 连接分两步:Term 先用 SSH 登上去,再让主机跑 mosh-server;等它把端口和密钥打出来,UDP 会话才开始。

所以这条错误说清楚了是哪一步失败的:SSH 成功了。地址、端口、用户名,还有你的密钥或密码,全都是对的,只是主机没能运行起 mosh-server。下面那行细节用应用自己的说法讲了同一件事:ServerNotFound。

Term 的连接界面:「已连接,但 mosh-server 未启动」、细节行 mosh-server bootstrap failed: ServerNotFound、「编辑主机」和「重试」按钮,以及一条「如何找到正确的路径」链接。
完整的失败画面:ServerNotFound 意味着 SSH 那一半没问题。在主机能找到这个可执行文件之前,重试不会有用;修复的地方在编辑主机里,底部那条链接打开的就是本页。

原因只有两种。要么这台主机上没装 mosh(那就装上,事情到此结束),要么装了但主机找不到它。本页余下的部分讲的是第二种,也是更让人困惑的一种,因为你自己敲 mosh 明明是好用的。

为什么你的 shell 找得到,Term 找不到

登录到主机、手敲 mosh-server,它跑得好好的。那 Term 为什么不行?

因为这不是同一种会话。你登录时,shell 会读它的启动文件(.profile、.bashrc、.zshrc),而包管理器正是在这些文件里把自己的目录加进 PATH 的。Term 启动 mosh 时并不开一个登录 shell,它只是通过 SSH 执行一条命令,相当于 ssh you@host mosh-server。这是非交互式会话,拿到的是 sshd 给的 PATH,通常只有:

非交互式 SSH 命令实际拿到的 PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

mosh-server 只要装在别处,对这条命令就是不存在的,而对你却一直好好地存在着。

这也解释了为什么同样的配置有人能用、有人不能:zsh 即便在非交互式下也会读 .zshenv,写在那里的 PATH 就能生效;而 bash 执行非交互式命令时 .bashrc 和 .profile 都不读。同一台主机、同样的安装,换个 shell,结果就不同。

找到它到底在哪

在你自己的电脑上执行两条命令。第一条用和 Term 相同的方式去问主机,用来确认诊断,它应该什么都不输出:

在你自己的机器上执行
# Term 看到的:没有输出,就是本页说的 PATH 问题
ssh you@host 'command -v mosh-server'

# 你看到的:登录 shell 能找到它
ssh you@host 'bash -lc "command -v mosh-server"'

第二条命令走的是登录 shell,也就是你平常登录时的环境。如果第一条没有输出、第二条打印出一个路径,那个路径就是答案:原样复制下来。

如果两条都没有输出,那就是这台主机上确实没装 mosh。用主机的包管理器装上即可,本页其余内容都用不到。

常见的位置

如果你更想直接试常见路径,下面这些几乎覆盖了所有情况。背后的规律始终一样:凡是把程序装在 /usr/bin 之外的包管理器,都是靠 shell 启动文件把自己的目录加进 PATH 的,而非交互式命令根本不会读那个文件。

macOS · Homebrew(Apple 芯片) /opt/homebrew/bin/mosh-server
macOS · Homebrew(Intel) /usr/local/bin/mosh-server
macOS · MacPorts /opt/local/bin/mosh-server
Nix · 用户 profile ~/.nix-profile/bin/mosh-server
Nix · 系统级(NixOS、nix-darwin) /run/current-system/sw/bin/mosh-server
FreeBSD · ports 与 pkg /usr/local/bin/mosh-server
装在自己家目录下 ~/bin/mosh-server 或 ~/.local/bin/mosh-server
Debian、Ubuntu、Fedora、Arch /usr/bin/mosh-server:本来就在 PATH 上,无需设置

这里可以用 ~:命令终究是在对端经由 shell 执行的,主机会自己展开它。想写得更明确,就写完整路径,/home/you/bin/mosh-server。

路径填在哪里

打开这台主机(失败界面上的编辑主机直接就到),找到连接。当传输方式是 Mosh 时,UDP 端口那一栏下面就是 mosh-server 命令(可选)。凡是 mosh 正常安装的主机都请留空;只有这种情形才需要它。

Term 主机编辑器里的「连接」卡片:SSH / Mosh / Telnet 选在 Mosh,一个 UDP 端口或范围输入框,以及一个空的「mosh-server 命令(可选)」输入框,下面是说明文字和一条链接。
连接 · Mosh,mosh-server 命令(可选)就排在 UDP 端口范围下面,因为两者回答的是同一个问题:这台主机怎样找到 mosh-server?
mosh-server 命令输入框里填着 /opt/homebrew/bin/mosh-server。
把主机打印出来的路径原样粘进去。保存、连接,会话就会像它本该的那样打开。

它是一条命令,而不只是一个路径,Term 会原样传过去:和 mosh 自己的 --server 选项收的是同一种东西。所以 sudo mosh-server 可以用,你自己写的、先做点准备再 exec 真正可执行文件的包装脚本也可以用。

还值得知道的几点

它只对这台主机生效

这个字段是按主机存的,和旁边的 UDP 端口范围一样。十台用 Homebrew 的 Mac 就要填十次,或者在服务器那侧把 PATH 一次修好,见下条。

另一种修法在服务器上

你也可以让字段留空,改为让主机自己找得到:把它软链到 /usr/local/bin,或为 zsh 在 ~/.zshenv 里设好 PATH,又或者给 sshd 加上 PermitUserEnvironment/SetEnv。这些做法改的是整台机器,对所有连上来的工具都生效;而这个字段只改 Term,而且只改这一台主机。两者谈不上谁更正确,只是后者你在手机上就能做。

把主机改回非 mosh 会清空它

把传输方式改回 SSH 或 Telnet,这条命令会和 UDP 端口一起被清掉,免得哪天你再把这台主机改回 mosh 时,一个过期的路径悄悄复活。

它不改变登录过程

SSH 那一半本来就是通的,那正是这条错误告诉你的。这里改的只是之后执行的那条命令。

延伸阅读:mosh 的进阶设置 · 常见问题 — 如何通过 mosh 连接