ソース("."または"source")とbashでのファイル実行の違いは何ですか?

ソース("."または"source")とbashでのファイル実行の違いは何ですか?

次のスクリプトを実行するときの違いは何ですか?

./test.sh

次のスクリプトを実行します。

. test.sh

違いが見つかるかどうかを確認するために、単純な2行のスクリプトを試しました。

#!/bin/bash
ls

ただし、どちらも同じ情報を. test.sh返します。./test.sh

答え1

./test.shtest.sh別のプログラムとして実行されます。ファイルが.bashrcでtest.sh始まる場合は、#!/bin/bashおそらくbashスクリプトです。しかし、それはまったく異なるものかもしれません。

. ./test.shtest.sh実行中のbashインスタンスでファイルコードを実行します。内容ファイルがtest.sh行ではなくテキストとして含まれているかのように機能します. ./test.sh。 (ほとんど:$BASH_LINENO組み込み関数の値や動作など、いくつかの詳細が異なりますreturn。)

source ./test.shbashと同じです(. ./test.sh他のシェルではsourceわずかに異なるか完全には存在しない可能性があり、.POSIX標準に含まれています)。

./test.sh組み込みスクリプトを使用して別々のスクリプトを実行することと組み込みスクリプトを含めることの最も一般的な違いは、スクリプトが.一部の環境変数を設定する場合、test.sh別のプロセスでは子プロセスの環境のみが設定されることです。スクリプトには環境変数が設定されます。単独のシェルプロセスが確立されました。呼び出しスクリプトに行を追加し、foo=bar最後test.shecho $foo違いを見ることができます。

$ cat test.sh
#!/bin/sh
foo=bar
$ ./test.sh
$ echo $foo

$ . ./test.sh
$ echo $foo
bar

答え2

最初の方法は、スクリプトをサブプロセスとして実行することです。一方、ソースコード(2番目の方法)は、現在のシェルにすべてのコマンドを入力したかのようにスクリプトを実行します。スクリプトが変数を設定すると設定されたままになり、スクリプトが終了するとセッションが終了します。help .リソースドキュメントを参照してください。

答え3

私が気づいたもう一つのことは、次のエイリアスがある場合です。

# add into .bashrc_aliases
alias ls='ls -lht'

これにより、./test.sh通常のls出力(現在のシェルとは異なるPID)が得られます。

auraham@pandora:~/iso$ ./test.sh 
dsl-4.4.10.iso  test.sh
3136 # PID

. test.shまたは、以下を使用すると、. ./test.shより詳細な出力(現在のシェルと同じPID)を取得できます。

auraham@pandora:~/iso$ echo $$
2767 # shell PID

auraham@pandora:~/iso$ . test.sh 
total 50M
drwxrwxr-x  2 auraham auraham 4.0K Jul 30 15:41 .
-rwxrwxr-x  1 auraham auraham   32 Jul 30 15:41 test.sh
drwxr-xr-x 50 auraham auraham 4.0K Jul 30 15:30 ..
-rw-rw-r--  1 auraham auraham  50M Jul 28 17:24 dsl-4.4.10.iso
2767 # PID

答え4

通常、aは./fileファイルを指す方法です。この場合、現在の作業ディレクトリ(PWD)パスの後に使用されるファイル名が続くのと同じです。

$ pwd
/home/isaac/me/bin/

$ realpath ./file
/home/isaac/me/bin/file

行の先頭のパス(最初の引数または引数0)は、ファイルの実行を試みるようにシェルにシグナルを送信することもできます。シェルスクリプトの場合、シェルはそれをロードして新しい実行環境で実行する可能性が高くなります。他の形式の有効な実行可能ファイルの場合、シェルはexecカーネルコマンドを介して実行を試みます。

コマンドラインに初期点を追加すると(フル引数が0の場合にのみ有効です)、すでに存在する同じ実行環境を使用してシェルスクリプト(外部実行ファイルではない)をロードできます。

$ . ./file        # that exact same file as above, now it is sourced
$ source ./file   # an equivalent (but longer) command.

もちろん、パスにディレクトリが設定されていない場合(ドットで始まらない)、インポートする特定のファイルを見つけるためにいくつかの検索が必要です。

バッシュから:

ファイル名にスラッシュが含まれていない場合は、PATHのファイル名を使用してファイル名を含むディレクトリを見つけます。

また、POSIX モードでは、PWD を使用してfilename与えられた値を取得します。

関連情報