web-dev-qa-db-ja.com

'echo $ 0'が2つの異なる端末に対して異なる結果を与えるのはなぜですか?

Ubuntuでターミナルを開いた Ctrl+Alt+T ディレクトリに移動して右クリックし、[ターミナルで開く]を選択すると、別のターミナルが表示されます。

echo $0 両方の場合において。

最初のケースでは:

$ echo $0
-bash

2番目の場合:

$ echo $0
/bin/bash

なぜこの違いがあるのですか?

15
CodeBlue

echo $0コマンドの出力が-bashの場合、bashがログインシェルとして呼び出されたことを意味します。出力がbashのみの場合は、ログインしていないシェルを使用しています。

man bashは、126行目のどこかで述べています。

A  login Shell is one whose first character of argument zero is a -, or 
one started with the --login option.

詳細については、こちらをご覧ください ログインシェルと非ログインシェルの違い?

さて、2番目のケースで/bin/bashを取得する理由を説明するために、プログラム(あなたの場合はファイルマネージャー、おそらくnautilus)またはスクリプトが独自の$0を別のものに変更できると言えます。例として、私の端末(常に同じ端末)で$0で何が起こっているかを確認します。

enter image description here

16
Radu Rădeanu

違いは、これらの開始方法にあります。 bashは、argv [0]に応じて異なる方法で初期化されます(異なる起動スクリプトを読み取ります)。文字列が-のようにハイフン-bashで始まる場合は、ログインシェルとして実行され、そうでない場合はインタラクティブシェルとして実行されます。また、非対話型シェル(つまり、シェルスクリプト内)として実行することもできます。

詳細については、マニュアルのman bash INVOCATIONセクションを読むことをお勧めします。

12
X Tian

シェルはログインしたときに開始されますが、makeなどのプログラムによって、またはシェルスクリプトを実行したとき、または:sh to viを入力したとき、または新しいターミナルウィンドウを作成します。

本来、シェルは、ログインまたはsuを実行したときに~/.profileを読み取りました。このスクリプトは、新しい電子メールが届いたかどうかを知らせ、消去文字と削除文字をカスタマイズし、TERM変数とPATH変数を設定してエクスポートするようなものです。他のほとんどのコンテキストで起動したとき、シェルは~/.profileを読み取れませんでした。これらのほとんどの作業は冗長になるためです。重要なシェル変数を新しいシェルにエクスポートしたはずです。

シェルが~/.profileを読み取るかどうかを知る方法は、argv[0]の最初の文字(別名$0)が'-'かどうかを確認することでした。

csh以降、エイリアスが導入されました。エイリアスは環境にエクスポートされませんでした。 cshは、2つの異なる初期化スクリプトを読み取るように設計されています。 ~/.loginは、ユーザーがログインしたときにのみ読み取られました。これを行うきっかけは、argv[0]'-'で始まっていた場合です。 ~/.cshrcは、シェルが起動されるたびに読み取られました。一般に、エイリアスは~/.cshrcに配置し、その他はすべて~/.loginに配置しました。 csh~/.logoutもサポートしています。これはほとんどの場合、画面をクリアしてfortuneを実行しただけです。

他のシェルはこれらと同じ機能を採用しています。 ksh~/.kshrcを読み取り、bash~/.bashrcを読み取り、それらがエイリアス定義を配置する場所でした。

したがって、話を簡単に言うと、シェルを生成するアプリケーションは、それが「ログインシェル」であるかどうかを判断します。この場合、最初に'-'が存在するか、通常のシェルが存在します。ほとんどの場合、対話型になるシェルはログインシェルとして起動され、シェルは引数としてまたはスクリプトからいくつかのコマンドを実行するためのものであり、通常のシェルです。

しかし、それはすべて、シェルを起動するアプリケーションの気まぐれ次第です。

9
Mark Plotnick