登入成功了,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 連線