5

bash のマンページを読んだところ、.bashrc は、シェルが対話的に実行されている場合にのみ実行する必要があります。マンページでは、インタラクティブを次のように定義しています。

対話型シェルとは、非オプションの引数と -c オプションなしで開始され、標準入力とエラーの両方が端末に接続されている ( isatty(3) によって決定される) シェル、または -i オプションで開始されたシェルです。PS1 が設定され、bash が対話型の場合は $- に i が含まれ、シェル スクリプトまたはスタートアップ ファイルでこの状態をテストできます。

それでも、コマンドが対話的に実行されないことを考えると、ssh でコマンドを実行すると、予想に反して .bashrc も実行されます。したがって、この動作はバグのように見えますが、私が試したすべてのバージョンの Red Hat と bash にも蔓延しているようです。この動作が正しい理由を誰かが説明できますか?

1 つの追加ポイント: .bashrc が実行さ$-$PS、シェルが非対話型であるかのように設定されていても (予想どおり)。

$ grep USER /etc/passwd
USER:x:UID:GID:UNAME:/home/USER:/bin/bash

$ cat ~/.bashrc
echo bashrc:$-,$PS1

$ bash -c 'echo $-'
hBc

$ ssh localhost 'echo $-' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
hBc

$ ssh localhost 'ps -ef | grep $$' </dev/null 2>/dev/null
USER@localhost's password:
bashrc:hBc,
USER 28296 28295 0 10:04 ? 00:00:00 bash -c ps -ef | grep $$
USER 28297 28296 0 10:04 ? 00:00:00 ps -ef
USER 28298 28296 0 10:04 ? 00:00:00 grep 28296

現在、.bashrc でテスト[[ $- = *i* ]]することでこの問題を回避していますが、そうする必要はないようです。

ホーム ディレクトリに .bashrc (および .ssh) 以外のファイルを含まない 1 つのサンプル サーバーの構成は次のとおりです。

$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 5.7 (Tikanga)

$ bash --version
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2005 Free Software Foundation, Inc.

これを試した bash のバージョン: 3.00.15、3.1.17、3.2.25、4.1.2 (Red Hat 6.3 では後者)。

4

1 に答える 1

3

Bashマニュアルから:

rshdBash は、リモート シェル デーモン (通常は) またはセキュア シェル デーモンによって実行されるときのように、ネットワーク接続に接続された標準入力で実行されているときを判別しようとしますsshd。Bash は、こ​​の方法で実行されていると判断した~/.bashrc場合、そのファイルが存在し、読み取り可能であれば、からコマンドを読み取り、実行します。sh として呼び出された場合、これは行われません。この--norcオプションは、この動作を禁止するために使用できます。オプションは、--rcfile別のファイルを強制的に読み取るために使用できますが、rshd通常、これらのオプションを使用してシェルを呼び出したり、それらを指定したりすることはできません。

デフォルトの Debianbashrcスケルトンでの回避策は、以下を の先頭に配置することです.bashrc

# If not running interactively, don't do anything
[ -z "$PS1" ] && return
于 2013-05-14T15:51:55.273 に答える