回答:
スクリプトをソースすると、現在のシェルプロセスでコマンドが実行されます。
実行スクリプトは、内のコマンドを実行します新しいシェルプロセス。
スクリプトで現在実行中のシェルの環境を変更する場合は、ソースを使用します。それ以外の場合はexecuteを使用します。
まだ混乱している場合は、読んでください。
実行する構文とソースの構文に関する一般的な混乱を明確にするには:
./myscript
これは、ファイルが実行可能で、現在のディレクトリにある場合に実行 myscript
されます。先頭のドットとスラッシュ(./
)は、現在のディレクトリを示します。これは、現在のディレクトリが通常ではない(通常はそうではない)ために必要$PATH
です。
myscript
これは、ファイルが実行可能で、のディレクトリにある場合に実行さ myscript
れ$PATH
ます。
source myscript
これはソースに なりますmyscript
。ファイルは実行可能である必要はありませんが、有効なシェルスクリプトでなければなりません。ファイルは、現在のディレクトリまたはのディレクトリにあり$PATH
ます。
. myscript
これもソースになり myscript
ます。この「スペル」は、POSIXで定義されている公式のものです。source
ドットのエイリアスとして定義されたbash 。
myscript.sh
次のコンテンツを検討してください。
#!/bin/sh
# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)
# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD
スクリプトを実行する前に、現在の環境を確認します。
$ env | grep FOO
$ echo $PWD
/home/lesmana
変数FOO
は定義されておらず、ホームディレクトリにいます。
次に、ファイルを実行します。
$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
環境を再度確認します。
$ env | grep FOO
$ echo $PWD
/home/lesmana
変数FOO
は設定されておらず、作業ディレクトリは変更されていません。
スクリプト出力は、変数が設定され、ディレクトリが変更されたことを明確に示しています。その後のチェックは、変数が設定されておらず、ディレクトリが変更されていないことを示しています。どうした?変更は新しいシェルで行われました。現在のシェルが起動され、新たなスクリプトを実行するシェルを。スクリプトは新しいシェルで実行されており、環境へのすべての変更は新しいシェルで有効になります。スクリプトの実行後、新しいシェルは破棄されます。新しいシェルの環境に対するすべての変更は、新しいシェルで破棄されます。現在のシェルでは、出力テキストのみが印刷されます。
次に、ファイルをソースします。
$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
環境を再度確認します。
$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir
変数FOOが設定され、作業ディレクトリが変更されました。
スクリプトを入手しても、新しいシェルは作成されません。すべてのコマンドは現在のシェルで実行され、環境への変更は現在のシェルで有効になります。
この単純な例では、実行の出力はスクリプトのソースと同じであることに注意してください。これは必ずしもそうとは限りません。
次のスクリプトを検討してくださいpid.sh
。
#!/bin/sh
echo $$
(特別な変数$$
は、現在実行中のシェルプロセスのPIDに展開されます)
まず、現在のシェルのPIDを出力します。
$ echo $$
25009
スクリプトを入手します。
$ source pid.sh
25009
スクリプトを実行します。PIDに注意してください。
$ ./pid.sh
25011
再びソース:
$ source pid.sh
25009
再実行:
$ ./pid.sh
25013
スクリプトを実行すると同じプロセスで実行され、スクリプトを実行すると毎回新しいプロセスが作成されることがわかります。その新しいプロセスは、スクリプトの実行用に作成された新しいシェルです。スクリプトを入手しても新しいシェルは作成されないため、PIDは変わりません。
これらのコマンドを1行ずつ手動で入力したかのように、スクリプトのソースと実行の両方で、スクリプト内のコマンドを1行ずつ実行します。
違いは次のとおりです。
スクリプトで現在実行中のシェルの環境を変更する場合は、ソースを使用します。それ以外の場合はexecuteを使用します。
こちらもご覧ください:
source myscript.sh
とは. myscript.sh
?
スクリプトを実行すると、別の子プロセスで実行されます。つまり、シェルの別のインスタンスが呼び出されて、スクリプトが処理されます。つまり、スクリプトで定義されている環境変数などは、親(現在の)シェルでは更新できません。
スクリプトのソースは、現在のシェル自体によって解析および実行されることを意味します。スクリプトの内容を入力したかのようです。このため、ソースとなるスクリプトは実行可能である必要はありません。ただし、もちろん実行する場合は実行可能でなければなりません。
現在のシェルに位置引数がある場合、それらは変更されません。
だから私がa.sh
含むファイルがある場合:
echo a $*
そして私は:
$ set `date`
$ source ./a.sh
私は次のようなものを得ます:
a Fri Dec 11 07:34:17 PST 2009
一方、
$ set `date`
$ ./a.sh
私に与えます:
a
お役に立てば幸いです。
スクリプトで定義されたすべての追加変数を取得します。
そのため、構成または関数定義がある場合は、実行せずにソースする必要があります。実行は、親環境から独立しています。
source
コマンドが提供されたスクリプトを実行(実行可能権限がある必須ではありません)で、現在ながら、シェル環境を./
提供する実行実行中のスクリプト新しいシェルを。
また、次の例の回答を確認してください:https : //superuser.com/a/894748/432100