登录成功了,mosh-server 却没启动。几乎总是 PATH 的问题,这里讲怎么找到它,以及让主机指向它。
需要 Term v26.1.0 或更高版本。
撰写于
mosh 连接分两步:Term 先用 SSH 登上去,再让主机跑 mosh-server;等它把端口和密钥打出来,UDP 会话才开始。
所以这条错误说清楚了是哪一步失败的:SSH 成功了。地址、端口、用户名,还有你的密钥或密码,全都是对的,只是主机没能运行起 mosh-server。下面那行细节用应用自己的说法讲了同一件事:ServerNotFound。
ServerNotFound 意味着 SSH 那一半没问题。在主机能找到这个可执行文件之前,重试不会有用;修复的地方在编辑主机里,底部那条链接打开的就是本页。原因只有两种。要么这台主机上没装 mosh(那就装上,事情到此结束),要么装了但主机找不到它。本页余下的部分讲的是第二种,也是更让人困惑的一种,因为你自己敲 mosh 明明是好用的。
登录到主机、手敲 mosh-server,它跑得好好的。那 Term 为什么不行?
因为这不是同一种会话。你登录时,shell 会读它的启动文件(.profile、.bashrc、.zshrc),而包管理器正是在这些文件里把自己的目录加进 PATH 的。Term 启动 mosh 时并不开一个登录 shell,它只是通过 SSH 执行一条命令,相当于 ssh you@host mosh-server。这是非交互式会话,拿到的是 sshd 给的 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 的,而非交互式命令根本不会读那个文件。
这里可以用 ~:命令终究是在对端经由 shell 执行的,主机会自己展开它。想写得更明确,就写完整路径,/home/you/bin/mosh-server。
打开这台主机(失败界面上的编辑主机直接就到),找到连接。当传输方式是 Mosh 时,UDP 端口那一栏下面就是 mosh-server 命令(可选)。凡是 mosh 正常安装的主机都请留空;只有这种情形才需要它。
mosh-server 命令(可选)就排在 UDP 端口范围下面,因为两者回答的是同一个问题:这台主机怎样找到 mosh-server?
它是一条命令,而不只是一个路径,Term 会原样传过去:和 mosh 自己的 --server 选项收的是同一种东西。所以 sudo mosh-server 可以用,你自己写的、先做点准备再 exec 真正可执行文件的包装脚本也可以用。
这个字段是按主机存的,和旁边的 UDP 端口范围一样。十台用 Homebrew 的 Mac 就要填十次,或者在服务器那侧把 PATH 一次修好,见下条。
你也可以让字段留空,改为让主机自己找得到:把它软链到 /usr/local/bin,或为 zsh 在 ~/.zshenv 里设好 PATH,又或者给 sshd 加上 PermitUserEnvironment/SetEnv。这些做法改的是整台机器,对所有连上来的工具都生效;而这个字段只改 Term,而且只改这一台主机。两者谈不上谁更正确,只是后者你在手机上就能做。
把传输方式改回 SSH 或 Telnet,这条命令会和 UDP 端口一起被清掉,免得哪天你再把这台主机改回 mosh 时,一个过期的路径悄悄复活。
SSH 那一半本来就是通的,那正是这条错误告诉你的。这里改的只是之后执行的那条命令。
延伸阅读:mosh 的进阶设置 · 常见问题 — 如何通过 mosh 连接