SSHのログインと非ログインのシェルは明らかに矛盾しています。

SSHのログインと非ログインのシェルは明らかに矛盾しています。

私はRHEL6(カーネル2.6.32-573.el6.x86_64)を実行しています。sshに入ったときに得たいくつかのエイリアスがありますmyserver。その一つは

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

非ログインシェル(以下を参照)でエイリアスを使用することは可能ですが、sshingはログインシェルを提供します。これは次の行で確認されます。

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

~/.bashrcでは

This is a login shell

予想通り。それで、エイリアスがなぜ/どこに設定されているのかわかりません。

矛盾のように見えるこの状況をどのように合理化できますか?


私のシステム上のファイル:

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

私のシステムにファイルがありません。

/etc/bash.bashrc
~/.profile


長い話を短く

エイリアスは次の行で設定されているようです(非ログインシェルのみ)/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

これはingのbash -x後にコマンドプロンプトで実行され(部分的に?)確認されましたssh

答え1

これは実際には通常の動作です。これは、ログインスクリプトと非ログインスクリプトソース用の異なるファイルに帰結します。これはすでに他の場所でも広く扱われるしかし、簡単に言えば、(対話型)非ログインのbashシェルはbashrcシリーズファイル(/etc/bash.bashrc、、~/.bashrc)を取得し、(対話型)ログインシェルはさまざまな設定ファイル(/etc/profile、、~/.profile)を取得します。

したがって、あなたの/etc/bashrc(私の考えでは、これは/etc/bash.bashrcmacOSや他のシステムと同じだと思います)対話型の非ログインシェルでのみ読むことができます。リモートシェルデーモン。この現象は、ファイルを読み取るときにファイルを読み取るシェルが非ログインシェル(したがってリモートシェルデーモンではない場合)でも発生します/etc/profile.d

ただし、ログインシェルはこのファイルを読み取らないため、ここでは関係ありません。代わりに、それらを読み、/etc/profileファイルを調べると、次のようなものが見つかります(/etc/profile私のアーチのファイルから)。

# 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

そのため、ログインシェルにこれらの内容を表示できます。これは、ログインシェルが正しく機能せず、代わりに次のファイルをインポートするがログインシェルを除外しない bashrc独自のインストールファイルがあるためです。/etc/profile.d

答え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を介して実行されたスクリプト/コマンドの追跡順序

関連情報