web-dev-qa-db-ja.com

Bash Shell:ポータブル構成ファイルとGUI端末の起動タイプ(ログインまたはインタラクティブ)を調整する方法は?

複数のプラットフォームで使用するために、私の好みのシェルの標準構成bashを「適切に」実装しようとして、シェルの起動の選択と矛盾する端末を扱うときに混乱が生じました。アップタイプ(ログインまたはインタラクティブ)。

Bashスタートアップファイル

Bashのマニュアルから、スタートアップファイルとそれらが供給される順序/ケースの違いを判断しました(ログインシェルの場合は/etc/profile~/.bash_profile~/.bash_login、および~/.profile、インタラクティブな非ログインシェルの場合は~/.bashrc)。ドキュメントでは、bash固有のログイン構成を~/.bash_profileに保存し、bash固有のインタラクティブな構成を~/.bashrcに保存することを提案しています。マニュアル自体は、ログインシェルがインタラクティブなシェル設定を継承するようにif [ -f ~/.bashrc ]; then source ~/.bashrc; fi~/.bash_profileファイルに追加することさえ提案しました。

マニュアルやさまざまなオンラインフォーラム/ドキュメントで読んだことから、他のシェルがこのファイルを入手できるため、bash以外の特定のログイン構成を~/.profileに抽象化することも賢明であるように思われました。これは、bashに加えてBourne Shellを使用する可能性のある人にとってはエッジケースかもしれませんが(私の場合はそうは思われません)、形成するのは良い習慣のようです。

これまでのところ、これはすべて非常に単純で論理的であるように思われます。特に、さまざまなシェル起動タイプの違いが明らかな環境では、コマンドラインがプライマリインターフェイスであるシステムまたは端末では、ログインシェルがプライマリセッションシェルです。 、インタラクティブシェルはそのセッションで起動される後続のシェルであり、非インタラクティブシェルはスクリプトを実行するシェルです。

本当の混乱は、すでにシステムに対して認証されているGUI環境内の端末からシェルを起動したときにログインシェルを構成するものですか? Mac OSX Terminal.appのデフォルトの動作は、各ウィンドウで実行されているシェルがログインシェルを開始することですが、xtermでは、新しい各ウィンドウはインタラクティブシェルです。


存在しない問題が発生している可能性がありますが、次のことを考慮してください。端末の状況は、bashを開始する端末で作業している場合に機能が失われないように、構成の大部分を~/.bashrcに配置することを示唆しています。インタラクティブシェル。 bashがインタラクティブシェルとして生成される可能性がある場合の複雑さに慣れていないため、 this ステートメントを信頼する必要があります。このように~/.bashrcを悪用すると、ログインシェル構成が誤って配置されると通常のシェル機能に悪影響を与えるという問題が最終的に発生します。 。マニュアルのアドバイスを無視して設定ファイルを不適切に使用すると、問題が発生する可能性があることは想像に難くありません。

~/.bashrcをキャッチオールとして使用することに実際に依存することはできないため、使用している端末によっては、~/.bash_profileファイルと~/.bashrcファイルを異なる方法で処理する必要があるようです。これは多くの頭痛の種になるようであり、そもそもこれらの別個の起動ファイルを持つという目的に反しています!

最後に、私の質問は次のとおりです。

  • 現在のBash Shellユーザーは、ログインの開始と対話型シェルの間のGUI端末の不整合の問題にどのように対処していますか?
  • 問題にぶつかることなく、クロスプラットフォーム(およびクロスターミナル)で使用するためのbash起動ファイルの単一セットをどのように作成しますか?

あなたの援助とアドバイスをありがとう。

5
jmlane

シェル起動ファイルの誤用によって引き起こされる最も一般的な問題は、.bashrcではなく.profileで環境変数を定義すると、端末のシェルから起動されないアプリケーションでは定義されないことです。 GUIメニューからではなく。

.bashrcから環境変数を定義することは一般的には良い考えではありませんが、これは主に、ログイン時に変数がすでに設定されているはずなので、一般的に役に立たないためです。あなた(またはアプリケーション)がプログラム内の変数(例:PATH)の値を意図的に変更し、そのプログラムからシェルを起動して設定が維持されることを期待している場合、実際には問題が発生する可能性があります。同じ。

「センチネル」値を定義し、センチネル値が設定されている場合は何も定義しないことで、環境変数がリセットされる問題を回避できます。

if [ -z "$JMLANE_PROFILE_READ" ]; then
  export ...
  export JMLANE_PROFILE_READ=1
fi

端末がログインシェルを開始することによって引き起こされる別の問題は、ログイン時に1回だけ実行する必要があることです。たとえば、パスワードエージェントの開始(例:ssh-agent)、セッションの開始(例:startx特定の状況で)。センチネル変数はこれらの問題を回避します。

端末内のシェルは常にインタラクティブです。シェルが対話型のときに.bashrcから.bash_profileを調達する限り、端末がログインシェルを開始することを心配する必要はありません。

Bashの起動ファイル処理の追加の警告は、.bashrcがrshdまたはsshdによって呼び出された非対話型シェルによって読み取られることです。たとえば、rsync somefile Host.example.com:を実行するときに、Host.example.comのログインシェルがbashの場合、そこで.bashrcを使用して、パスにrsyncを含めることができます。 .bashrcは非対話型シェルから読み取られるため、この状況にあることがわかります。

## .bashrc
if [[ $- != *i* ]]; then
  # either .bashrc was executed explicitly or this is a noninteractive rsh/ssh session
fi