明らかに、SSH でのログイン シェルと非ログイン シェルは矛盾している

明らかに、SSH でのログイン シェルと非ログイン シェルは矛盾している

私はRHEL6 (カーネル 2.6.32-573.el6.x86_64) を実行しています。sshに入力する際に​​参照されるエイリアスがありますmyserver。そのうちの1つは

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

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

答え1

これは実際には正常な動作です。これは、ログインスクリプトと非ログインスクリプトによって取得されるファイルの違いによるものです。これは他の場所で広く取り上げられている簡単に言うと、(対話型の)非ログイン bash シェルは bashrc ファミリのファイル ( /etc/bash.bashrc~/.bashrc) をソースとし、(対話型の)ログイン シェルはさまざまなプロファイル ファイル ( /etc/profile~/.profile) をソースとします。

つまり、あなたの/etc/bashrc(macOSや他のシステムと同等だと思います/etc/bash.bashrc)は、インタラクティブな非ログインシェルによってのみ読み取られ、リモート シェル デーモン. そのファイルが読み取られるとき、それを読み取るシェルが非ログイン シェル (つまりリモート シェル デーモンではない) である場合は、 の下にある特定のファイルも読み込まれます/etc/profile.d

ただし、ログイン シェルはこのファイルを読み取らないため、ここでは関係ありません。代わりに、このファイルを読み取るので/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

そのため、ログイン シェルでこれらが表示されるのです。これは、ログイン シェルが機能せず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 で実行されたスクリプト/コマンドのシーケンスをトレースします

関連情報