Linux

/etc/profile.d 和“ssh -t”

  • December 4, 2017

我想在遠端機器上執行一個腳本。簡單的解決方案是這樣的:

ssh remote1 some-script

這一直有效,直到遠端腳本不想連接到remote2需要互動式身份驗證的另一台遠端電腦(),例如 tis one(在這種情況下remote2只能通過):remote1

ssh remote1 "ssh remote2 some-script"

該問題的解決方案是使用-tssh 選項。

ssh -t remote1 "ssh remote2 some-script"

這可行,但如果我使用它(some-script可能會執行進一步的 ssh 命令),我會得到探測:

ssh -t remote1 some-script

我發現有些環境變數是在我不使用該-t選項時設置的。這些環境變數是在腳本中設置的/etc/profile.d。我猜如果使用該選項,這些腳本由於某種原因不會執行-t,但如果我不使用它,它們就會執行。

這是什麼原因?有沒有辦法解決它?我正在使用 SUSE linux(版本 10)。

**編輯:**我做了一些額外的研究。我將一些輸出行放在以下位置:

  • 在一個文件中/etc/profile.d
  • in ~/.bash_profile(文件以前不存在)
  • in ~/.bashrc(文件以前不存在)

然後我檢查了幾個場景我得到了什麼輸出以及以什麼順序(我檢查的環境變數是$PATH):

  • ssh remote1: profile.d, .bashrc, .bash_profile. $PATH好的。
  • ssh -t remote1: profile.d, .bashrc, .bash_profile. $PATH好的。
  • ssh remote1 echo '$PATH': 只有.bashrc$PATH好的。
  • ssh -t remote1 echo '$PATH': 沒有腳本輸出。$PATH挪威克朗。

現在我真的不明白髮生了什麼。如果我執行一個互動式 shell,一切似乎都執行良好(儘管我覺得~/.bashrc之前包含的內容很奇怪~/.bash_profile)。如果我在沒有 的情況下啟動非互動式 shell -t,則配置文件腳本似乎不會執行,但會設置環境變數。如果我使用 啟動非互動式 shell -t,則不會執行配置文件腳本並且未設置環境變數。有人對此有解釋嗎?

我沒有找到問題的原因。也許它特定於平台(SLES 10 或我使用的變體)。我找到了一種解決方法:

ssh -t remote1 "/bin/bash --login -c some-script"

這會強制執行配置文件腳本的登錄 shell。

所有問題都在 bash 手冊頁的“INVOCATION”部分得到解答:

當 bash 作為互動式登錄 shell 或作為帶有 –login 選項的非互動式 shell 呼叫時,它首先從文件 /etc/profile 中讀取並執行命令(如果該文件存在)。讀取該文件後,它會按順序查找 ~/.bash_profile、~/.bash_login 和 ~/.profile,然後從第一個存在且可讀的文件中讀取並執行命令。當 shell 啟動時,可以使用 –noprofile 選項來禁止這種行為。

當登錄 shell 退出時,bash 從文件 ~/.bash_logout(如果存在)讀取並執行命令。

當一個不是登錄 shell 的互動式 shell 啟動時,bash 會從 ~/.bashrc 讀取並執行命令,如果該文件存在的話。這可以通過使用 –norc 選項來禁止。–rcfile 文件選項將強制 bash 從文件而不是 ~/.bashrc 讀取和執行命令。

如您所見,互動式 shell 僅 source .bashrc,並且通常.bash_profile會從那裡獲取,這解釋了您所看到的順序。

很多時候,這些文件也有一個條件,即只為互動式 shell 解析某些部分 ( [[ $- == *i* ]]),這可以解釋為什麼某些部分對於非互動式 shell 可能似乎缺失。

引用自:https://serverfault.com/questions/441717