ssh 上的登入與非登入 shell 顯然是矛盾的

ssh 上的登入與非登入 shell 顯然是矛盾的

我正在運行 RHEL6(核心 2.6.32-573.el6.x86_64)。我有一些別名,這些別名是在sshing into時取得的myserver。其中之一是

alias scl-devtoolset-3='source /usr/local/bin/scls/devtoolset-3'

它可能在非登入 shell 中使用別名(見下文),但sshing 給出了登入 shell,並且這一點由以下行確認

shopt -q login_shell && echo 'This is a login shell' || echo 'This is a non-login shell'

在 my 中~/.bashrc,它產生

This is a login shell

正如預期的那樣。因此,我不知道為什麼/在哪裡設定了別名。

如何合理化這種看似矛盾的情況?


我的系統中存在的檔案:

/etc/profile
/etc/bashrc
/etc/profile.d/*
~/.bashrc

我的系統中不存在檔案:

/etc/bash.bashrc
~/.profile


長話短說

別名似乎是透過以下行設定的(僅在非登入 shell 中)/etc/bashrc

...
if ! shopt -q login_shell ; then # We're not a login shell
    ...
    # Only display echos from profile.d scripts if we are no login shell
    # and interactive - otherwise just process them to set envvars
    for i in /etc/profile.d/*.sh; do
        if [ -r "$i" ]; then
            if [ "$PS1" ]; then
                . "$i"
            else
                . "$i" >/dev/null 2>&1
            fi
        fi
    done
...
fi

哪個來源檔案/etc/profile.d/scl-aliases.sh包含

#!/bin/bash

sources_dir=/usr/local/bin/scls

for scl in `ls $sources_dir`; do
        alias scl-$scl="source $sources_dir/$scl"
done

鑑於

$ ls /usr/local/bin/scls
devtoolset-3  devtoolset-4  devtoolset-6  python27  python33

這是(部分?)透過在 ingbash -x之後在命令提示字元中執行來確認的ssh

答案1

這實際上是正常行為。這歸結為登入腳本與非登入腳本來源的不同檔案。這已經是其他地方廣泛涵蓋但是,簡單地說,(互動式)非登入 bash shell 取得 bashrc 系列檔案(/etc/bash.bashrc~/.bashrc),(互動式)登入 shell 取得各種設定檔(/etc/profile~/.profile)。

因此,您的/etc/bashrc(我認為這相當於/etc/bash.bashrcmacOS 以及其他系統上的)只能由互動式非登入 shell 讀取,並且遠端 shell 守護程式。當讀取該檔案時,如果讀取該檔案的 shell 是非登入 shell(因此不是遠端 shell 守護程序),它也會引入/etc/profile.d.

但是,登入 shell 不會讀取此文件,因此它與此處無關。相反,他們會讀取/etc/profile,如果你檢查該文件,你會發現類似這樣的內容(來自/etc/profile我的 Arch 上的文件):

# Load profiles from /etc/profile.d
if test -d /etc/profile.d/; then
    for profile in /etc/profile.d/*.sh; do
        test -r "$profile" && . "$profile"
    done
    unset profile
fi

這就是為什麼您會在登入 shell 中看到這些內容。這是因為登入 shell 無法正常工作bashrc,而是有自己的設定文件,這些文件會引入以下文件,/etc/profile.d但不排除登入 shell。

答案2

鑑於註釋不能包含縮排程式碼,我將其發佈為答案。感謝特登的回答

正如 terdon 所說,我/etc/profile的有以下幾行。

for i in /etc/profile.d/*.sh ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null 2>&1
        fi
    fi
done

這些將負責別名,而不是/etc/bashrc。這可以透過解決方案輕鬆驗證追蹤 ssh 上執行的腳本/命令的序列

相關內容