/etc/profile.d 和“ssh -t”
我想在遠端機器上執行一個腳本。簡單的解決方案是這樣的:
ssh remote1 some-script
這一直有效,直到遠端腳本不想連接到
remote2
需要互動式身份驗證的另一台遠端電腦(),例如 tis one(在這種情況下remote2
只能通過):remote1
ssh remote1 "ssh remote2 some-script"
該問題的解決方案是使用
-t
ssh 選項。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 可能似乎缺失。