短い答え
あなたの質問では、2番目のコマンドは.
シェル組み込みコマンドも組み込みコマンドも使用していませんsource
。代わりに、他の実行可能ファイルと同じように名前でスクリプトを呼び出すことにより、実際に別のシェルでスクリプトを実行しています。これは(かかわらず、それを変数の別のセットを与えないあなたがいる場合エクスポート変数を親シェルで、それはすべての子プロセスの環境変数となり、そのため、子シェルの変数に含まれます)。を/
スペースに変更すると、.
組み込みで実行されsource
ます。これはと同等です。
拡張説明
これはsource
シェル組み込みの構文で、現在のシェル内のスクリプトの内容を実行します(したがって、現在のシェルの変数を使用します)。
source testenv.sh
これは.
組み込みの構文であり、次と同じことを行いsource
ます。
. testenv.sh
ただし、次の構文はスクリプトを実行可能ファイルとして実行し、新しいシェルを起動して実行します。
./testenv.sh
それは.
組み込みを使用していません。むしろ、.
実行中のファイルへのパスの一部です。一般的に、少なくとも1 /
文字を含む名前で起動することにより、シェルで実行可能ファイルを実行できます。./
したがって、現在のディレクトリでファイルを実行するには、その前にファイルを置くのが最も簡単な方法です。現在のディレクトリがにない限り、PATH
コマンドでスクリプトを実行することはできませんtestenv.sh
。これは、PATH
環境変数にリストされているディレクトリに存在するシステムコマンドまたはその他のファイルを実行するときに、現在のディレクトリのファイルを誤って実行することを防ぐためです。
ファイルを(source
またはではなく.
)名前で実行すると、新しいシェルで実行されるため、独自のシェル変数のセットがあります。新しいシェルは呼び出しプロセス(この場合は対話型シェル)から環境変数を継承し、それらの環境変数は新しいシェルのシェル変数になります。ただし、シェル変数を新しいシェルに渡すには、次のいずれかが必要です。
シェル変数がエクスポートされたため、環境変数になりました。export
これには組み込みのシェルを使用します。例では、を使用export MY_VAR=12345
して変数を1ステップで設定およびエクスポートできますexport MY_VAR
。既に設定されている場合は、単に使用できます。
シェル変数は、実行中のコマンドに対して明示的に設定および渡されるため、実行中のコマンドの実行中は環境変数になります。これは通常、次のことを実現します。
MY_VAR=12345 ./testenv.sh
場合はMY_VAR
、エクスポートされていないシェル変数をある、あなたも実行することができますtestenv.sh
しMY_VAR
て、環境変数として渡された自分自身にそれを設定します:
MY_VAR="$MY_VAR" ./testenv.sh
./
スクリプトの構文を機能させるにはハッシュバンラインが必要です(正確に)
ちなみに、上記の名前で実行可能ファイルを呼び出した場合(.
またはsource
シェル組み込みコマンドではなく)、実行するシェルプログラムは通常、実行元のシェルによって決定されないことに注意してください。代わりに:
バイナリファイルの場合、カーネルはその特定の種類のファイルを実行するように構成できます。ファイルの最初の2バイトを調べて、それがどのようなバイナリ実行可能ファイルであるかを示す「マジックナンバー」を探します。これが、実行可能バイナリの実行方法です。
もちろん、これは非常に重要です。なぜなら、スクリプトは、実行可能なバイナリであるシェルまたは他のインタープリターなしでは実行できないからです!さらに、多くのコマンドとアプリケーションは、スクリプトではなくコンパイルされたバイナリです。
(#!
テキストの実行可能ファイルを示す「マジックナンバー」のテキスト表現です。)
シェルまたは他のインタプリタ言語で実行することになっているファイルの場合、最初の行は次のようになります。
#!/bin/sh
/bin/sh
プログラムを実行するための他のシェルまたはインタープリターで置き換えられます。たとえば、Pythonプログラムは次の行で始まる場合があります。
#!/usr/bin/python
これらの行は、hashbang、shebang、および他の多くの同様の名前と呼ばれます。このFOLDOCエントリ、このウィキペディアの記事、および#!/ bin / shはインタープリターによって読み取られますか?詳細については。
テキストファイルがされている場合は、実行可能とマークし、あなたは(のようなあなたのシェルから実行します./filename
)が、それはしていませんで始まり#!
、カーネルは、それを実行に失敗しました。ただし、これが発生すると、シェルはその名前を何らかのシェルに渡して実行しようとします。ありますいくつかの要件に置か何それは(あるシェル「シェルは、シェルが起動されたとコマンド相当を実行するものとは...」)。実際には、*を含むいくつかのシェルbash
は自分自身の別のインスタンスを実行し、他のは/bin/sh
。これを避けて、代わりにhashbang行を使用することを強くお勧めします(または、スクリプトを目的のインタープリター(例:)に渡すことで実行しますbash filename
)。
* GNU Bashマニュアル、3.7.2コマンドの検索と実行:「ファイルが実行可能な形式ではなく、ファイルがディレクトリではないためにこの実行が失敗した場合、シェルスクリプトであると見なされ、シェルは説明どおりに実行しますでシェルスクリプト。」
source
と思ったのは、関数をbashからロードまたは再起動する必要なく利用できるようになったことです。例#!/bin/bash function olakease {echo olakease;}
。一度ロードsource file.sh
するとolakease
、bashから直接呼び出すことができます。本当に好きです。ソースが実行され、多くのものがロードされます。ドット.
は実行専用で、使用のようなものですbash file.sh