結論/TLDR

結論/TLDR

私のアーチのインストールには次の行が/etc/bash.bashrcあります。/etc/skel/.bashrc

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

Debian には/etc/bash.bashrc次のものがあります。

# If not running interactively, don't do anything
[ -z "$PS1" ] && return

そして/etc/skel/.bashrc

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

しかしによると、man bash非対話型シェルは次のファイルも読みません。

たとえば、bash非対話型で実行されているときにシェルスクリプトを実行するには、環境内で変数を探し、BASH_ENVその変数が環境にある場合はその値を拡張し、拡張値を読み取るファイル名として使用します。 Bashは、次のコマンドが実行されたかのように動作します。if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fiただし、変数値はPATHファイル名の取得には使用されません。

私が正しく理解した場合、*.bashrcこのファイルはそのファイルを指すように設定されている場合にのみ読み取られます。BASH_ENVこれは偶然起こり得ないことであり、誰かがそれに応じて変数を明示的に設定した場合にのみ発生します。

.bashrcこれは、ユーザーフィードを自動的にインポートするスクリプトを設定する可能性を破るように見えます。BASH_ENVこれは便利です。 bashが明示的に指示しない限り、非対話式で実行されたときにこれらのファイルを決して読み取らないことを考えると、基本*bashrcファイルがそれを許可しないのはなぜですか?

ベストアンサー1

これは私が数週間前にここに投稿しようとした質問です。良いテデン、私はインタラクティブBashシェルでのみ発生することを知っているので、インタラクティブシェルで実行されていることを確認する.bashrc必要はありません。.bashrc混乱しても、みんな私が使用しているディストリビューション(Ubuntu、RHEL、およびCygwin)は、現在のシェルがインタラクティブであることを確認するために一種のテスト(テストまたは$-)を実行します。$PS1私は好きではない貨物崇拝プログラミングだから私は私を理解し始めました.bashrc

Bashにはリモートシェルのための特別なケースがあります。

この問題を調査して発見しました。リモートシェル別の方法で扱われます。非対話型Bashシェルは通常~/.bashrc起動時にコマンドを実行しませんが、シェルの起動時に特別な状況が発生します。リモートシェルデーモンによって呼び出された:

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

はい

リモートの先頭に以下を挿入します.bashrc。 (.bashrcまたはで起動した場合、テスト中にこの機能は一時的に無効になります。).profile.bash_profile

echo bashrc
fun()
{
    echo functions work
}

次のコマンドをローカルで実行します。

$ ssh remote_host 'echo $- $0'
bashrc
hBc bash
  • いいえ、iシェル$-非対話型
  • 紹介がない場合は、シェルではない-ことを示します。$0ログインシェル

リモートで定義されたシェル機能.bashrcも実行できます。

$ ssh remote_host fun
bashrc
functions work

私は~/.bashrcそれだったことに気づいた。ただコマンドが引数として指定されたときに取得されますssh。これは意味があります。ssh通常のログインシェルを起動.profileまたは.bash_profile実行するために使用される場合(.bashrcこれらのファイルのいずれかが明示的にこれを実行している場合にのみソースを取得します)。

.bashrc(非対話型)リモートコマンドを実行するときにソースを使用することで得られる主な利点は、シェル機能を実行できることです。ただし、一般的なコマンドの大部分は.bashrc対話型シェルでのみ関連しています。たとえば、シェルが対話型でない場合、エイリアスは拡張されません。

リモートファイル転送が失敗することがある

rshsshこれは、対話型ログインシェルを起動したり、非対話型シェルを使用してコマンドを実行したりする場合は通常問題ではありません。しかしそれは問題になる可能性がありますrcp次のようなscpプログラムの場合sftpリモートシェルデータの転送に使用されます。

scpそのコマンドを使用すると、リモートユーザーのデフォルトシェル(Bashなど)が暗黙的に起動されることがわかりました。マニュアルページにはこれに対する言及はありません。これscpはデータ転送の目的だけです。sshこれの結果は次のとおりです。.bashrc標準出力として印刷するコマンドが含まれていると、ファイル転送は失敗します。、例えば、 エラーなしでscpが失敗する

15年前のRed Hatバグレポートもご覧ください。/etc/bashrc に echo コマンドがある場合、scp は中断されます。(最終的に閉鎖されたWONTFIX)。

なぜ失敗scpしたのかsftp

SCP(セキュリティコピー)そしてSFTP(セキュリティファイル転送プロトコル)ローカルおよびリモート側には、転送されるファイルに関する情報を交換するための独自のプロトコルがあります。リモート側の予期しないテキストはプロトコルの一部として(誤って)解釈され、転送が失敗します。によるとカタツムリ本FAQ

ただし、ユーザーが読みやすいように、ログイン時にテキストメッセージを出力するステートメント(たとえば、、など)は、サーバー上のシステムまたはユーザー固有のシェル起動ファイル(.bashrc、、など)に頻繁に発生します。.profile/etc/csh.cshrc.loginfortuneecho "Hi there!"

標準入力に追加されると、これらのコードは対話型ログインでのみ出力を生成する必要があります tty。このテストを実行しないと、これらのテキストメッセージが属していない場所に挿入されます。この場合、scp2/との間sftpのプロトコルフローを汚染しますsftp-server

シェル起動ファイルは、次の理由で関連しています。sshd ユーザーの代わりにプログラムを起動するときにユーザーのシェルを使用します。 (例:/bin/sh -c「コマンド」を使用してください)。これはUnixの伝統であり、次の利点があります。

  • ユーザーの共通設定(コマンドエイリアス、環境変数、umaskなど)は、リモートコマンドの実行時に適用されます。
  • 何らかの理由で認証がまだ予期せず成功している場合は、/bin/false に設定してアカウントのシェルを無効にする一般的な慣習によって、所有者はどのコマンドも実行できません。

SCPプロトコルの詳細

SCPの仕組みについて詳しく知りたい方のために、以下で興味深い情報を見つけました。SCPプロトコルの仕組み詳細を含むリモート側でセッションシェルプロファイルを使用してscpを実行できますか?:

たとえば、リモートシステムのシェル設定ファイルに以下を追加すると、これが発生する可能性があります。

エコ「」

なぜそれは止まったのですか?これはscpどのように由来します源泉モードは、最初のプロトコルメッセージの承認を待ちます。バイナリゼロでない場合は、これをリモート問題の通知と見なし、新しい行が到着するまで、より多くの文字がエラーメッセージを生成するのを待ちます。最初の行以降は他の行を印刷しないため、ローカルファイルがscpループに閉じ込められてブロックされますread(2)。一方、リモート側でシェルプロファイルが処理された後、受信者モードがscp開始され、このモードもブロックされます。read(2)、データ転送の開始を示すバイナリゼロを待っています。

結論/TLDR

一般的なステートメントのほとんどは、.bashrc対話型シェルにのみ役立ちます。rshリモートコマンドを使用または実行しても効果はありませんssh。ほとんどの場合、シェル変数、エイリアスを設定し、関数を定義する必要はありません。すべてのテキストscpまたは、同じプログラムを使用してファイルを転送すると、標準出力は非常に有害である可能性がありますsftp。現在のシェルが非対話型であることを確認して終了します.bashrc

おすすめ記事