透過 SSH 進入 MacOS 時設定 PATH

透過 SSH 進入 MacOS 時設定 PATH

我的問題是

$ ssh localhost fswatch          
bash: fswatch: command not found

當沒有 SSH 指令(即 fswatch)時運作正常。

我發現 SSH 會話中的 PATH 是預設的 Mac 的

$ ssh localhost echo \$PATH        
/usr/bin:/bin:/usr/sbin:/sbin

因為沒有 SSH

$ echo $PATH
/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

我真的不記得我是如何設定 PATH 的,但可以肯定的~/.bashrc是,~/.bash_profile不要編輯 PATH 變數。有一個設定檔/etc/paths

$ cat /etc/paths         
/usr/local/bin
/usr/bin
/bin
/usr/sbin
/sbin

Homebrew、npm、pip 通常會將程式安裝到/usr/local/bin,因此所有已安裝的程式都在那裡,我無法透過ssh localhost command我的 MacOS 存取它們。 Linux下沒有問題。

所以我的問題是如何配置 OpenSSH 以使用來自/etc/paths和 的PATH/etc/paths.d?

我也嘗試破解:

$ ssh localhost sh -lc 'echo empty;echo $PATH'

/usr/bin:/bin:/usr/sbin:/sbin
$ ssh localhost bash -lc 'echo empty;echo $PATH'

/usr/bin:/bin:/usr/sbin:/sbin

第一行總是空的,你不知道為什麼嗎?

以及我的最終解決方法

$ ssh localhost bash -lc ':; 
    export PATH="$( cat /etc/paths /etc/paths.d/* | tr \\\\n : )"; 
    echo $PATH; 
    fswatch --version'
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/X11/bin:/Applications/VMware Fusion.app/Contents/Public
fswatch 1.14.0
Copyright (C) 2013-2018 Enrico M. Crisostomo <[email protected]>.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Enrico M. Crisostomo.

這裡第一個:;很重要,因為第一個命令以某種方式從執行中刪除

系統:MacOS Mojave 10.14.5
ssh -VOpenSSH_7.9p1, LibreSSL 2.7.3
bash --version GNU bash, version 5.0.7(1)-release (x86_64-apple-darwin18.5.0)

答案1

您可以設定 SSH 伺服器以為客戶端提供自訂環境,包括自訂PATH變數。您需要配置兩件事:

  1. ~/.ssh/environment在伺服器上建立包含以下內容的檔案:

    PATH=/Users/kyb/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
    
  2. 變更 SSH 伺服器設定檔/private/etc/ssh/sshd_config以包含以下行:

    PermitUserEnvironment PATH,LANG
    

最後,重新啟動/重新載入伺服器上的 SSH 守護程式。 SSH 登入用戶端應該可以存取您的自訂環境!

答案2

在我的系統上我可以編輯.bashrc並放置這個在最頂部:

PATH=/my/path:$PATH

將其放在前面很重要:

# If not running interactively, skip the rest
[ -z "$PS1" ] && return

答案3

對於我的回答,我假設您正在使用 Bourne Again SHell,但以下情況也適用於大多數其他 shell:

觀察到的行為的原因是,您的命令不會在互動式 shell 中運行,而是在非互動式 shell 中運行:

當伺服器接受使用者的身份時,伺服器要么在非互動式會話中執行給定的命令,要么如果未指定命令,則登入電腦並為使用者提供正常的 shell 作為互動式會話。所有與遠端命令或 shell 的通訊都將自動加密。

-$ man ssh

我懷疑你在你內部的某個地方.bashrc擴展了你的PATH變數。但.bashrc如果您不執行互動式 shell,BASH 將不會解釋您的檔案:

什麼時候啟動一個不是登入 shell 的互動式 shell,bash 從 /etc/bash.bashrc 和 ~/.bashrc 讀取並執行命令(如果這些檔案存在)。

-$ man bash

因此,解決此問題的最簡單的解決方案是提供可執行檔的完整路徑,例如:$ ssh localhost /full/path/to/fswatch這是此問題最穩定、最安全的解決方案,並且始終有效!

當您連線到時,localhost您可以利用which命令:$ ssh localhost $(which fswatch)。但是,當您連接到另一台主機時,這很可能不起作用。

另一種可能的方法是操縱PATH非互動式 shell 的遠端主機的環境變數(請參閱@hedgie 的答案)。然而,這會帶來安全隱患,因此不應在生產中使用:

啟用環境處理可以使用戶能夠使用 LD_PRELOAD 等機制繞過某些配置中的存取限制。

-man sshd_config

相關內容