‹ 指南

找不到 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 連線