私のアーチのインストールには次の行が/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
起動時にコマンドを実行しませんが、シェルの起動時に特別な状況が発生します。リモートシェルデーモンによって呼び出された:
rshd
Bashは、リモートシェルデーモン(通常)またはセキュアシェルデーモンによって実行されるときなど、ネットワーク接続に接続されている標準入力で実行されていることを確認しようとします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
対話型シェルでのみ関連しています。たとえば、シェルが対話型でない場合、エイリアスは拡張されません。
リモートファイル転送が失敗することがある
rsh
ssh
これは、対話型ログインシェルを起動したり、非対話型シェルを使用してコマンドを実行したりする場合は通常問題ではありません。しかしそれは問題になる可能性があります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
.login
fortune
echo "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
。