主な違いは、異なるプロセスで実行されることです。
source
の場合 ファイル foo
cd
を行う 、ソーシング シェル (ターミナル内のインタラクティブ シェルなど) が影響を受けます (現在のディレクトリが変更されます)
sh foo
を実行すると cd
ソースシェルには影響せず、新しく作成された sh
のみに影響します foo
を実行しているプロセス
高度な Bash スクリプト ガイドをお読みください。
他の人が言及したように、 sh test.sh
を実行すると 、 test.sh
の変更 プロセスが終了すると、シェル環境への make は保持されません。
ただし、エクスポートされていない環境の要素 (変数、エイリアス、シェル関数など) は test.sh
のコードでは使用できないことにも注意してください。 サブプロセスとして実行される場合 (つまり、sh test.sh
を使用) ).
例:
$ cat > test.sh
echo $foo
$ foo=bar
$ sh test.sh
$ . test.sh
bar
例 2:
[email protected]:~$ cat test.sh
#!/bin/sh
cd /etc
[email protected]:~$ sh test.sh
[email protected]:~$ pwd
/home/savoury
[email protected]:~$ source test.sh
[email protected]:/etc$ pwd
/etc
[email protected]:/etc$
source
に電話すると または .
(一方は他方のエイリアスです。source
cmd not POSIX - 一種の bashism )、シェルスクリプトを現在のにロードして実行します シェルプロセス .
- ソース スクリプトに設定された変数を読み取る
- その中で定義された関数を使用します。
- さらに、スクリプトがこれを行う場合、フォークやサブプロセスを実行します。
sh
に電話すると 、フォークを開始します (サブプロセスまたは 子 ) /bin/sh
の新しいセッションを実行します (多くの場合、これは bash
へのシンボリック リンクです) )。この場合、サブスクリプトによって設定された環境変数は、サブスクリプトが終了すると削除されます。
注意 :sh
別のへのシンボリックリンクである可能性があります
実践例
たとえば、現在の作業ディレクトリを変更したい場合 特定の方法では、できませんでした
$ cat <<eof >myCd2Doc.sh
#!/bin/sh
cd /usr/share/doc
eof
$ chmod +x myCd2Doc.sh
これは期待どおりに動作しません:
$ cd /tmp
$ pwd
/tmp
$ ~/myCd2Doc.sh
$ pwd
/tmp
なぜなら 現在の作業ディレクトリ 環境と myCd2Doc.sh
の一部です サブシェルで実行されます .
ただし:
$ cat >myCd2Doc.source <<eof
# Shell source file
myCd2Doc() {
cd /usr/share/doc
}
eof
$ . myCd2Doc.source
$ cd /tmp
$ pwd
/tmp
$ myCd2Doc
$ pwd
/usr/share/doc
mycd
を見てください 関数!! (Associative Array に基づく bash 補完あり) ).
実行レベル $SHLVL
$ cd /tmp
printf %b '\43\41/bin/bash\necho This is level \44SHLVL.\n' >qlvl.sh
$ bash qlvl.sh
This is level 2.
$ source qlvl.sh
This is level 1.
再帰 (スクリプトがそれ自体から実行される場合)
$ cat <<eoqlvl2 >qlvl2.sh
#!/bin/bash
export startLevel recursionLimit=5
echo This is level $SHLVL started:${startLevel:=$SHLVL}.
(( SHLVL < recursionLimit )) && ./qlvl2.sh
eoqlvl2
$ chmod +x qlvl2.sh
$ ./qlvl2.sh
This is level 2 started:2.
This is level 3 started:2.
This is level 4 started:2.
This is level 5 started:2.
$ source qlv2.sh
This is level 1 started:1.
This is level 2 started:1.
This is level 3 started:1.
This is level 4 started:1.
This is level 5 started:1.
もう少し
$ sed '$a ps --sid $SID fw' qlvl.sh >qlvl3.sh
$ chmod +x qlvl3.sh
$ export SID
$ read SID < <(ps ho sid $$)
$ echo $SID $$
8983 8983
(現在の PID ($$
==プロセス ID ) は SID と同じ識別子です (セッション ID )。常に正しいとは限りません。)
$ ./qlvl3.sh
This is level 2.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10266 pts/10 S+ 0:00 \_ /bin/bash ./qlvl3.sh
10267 pts/10 R+ 0:00 \_ ps --sid 8983 fw
$ . qlvl3.sh
This is level 1.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10428 pts/10 R+ 0:00 \_ ps --sid 8983 fw
ドット .
source
のエイリアスです .したがって、2 つのコマンドの唯一の違いは slash
です。 space
に置き換え .
そしてファイナル テスト:
$ printf %b '\43\41/bin/bash\necho Ending this.\nsle' \
'ep 1;exit 0\n' >finalTest.sh
$ bash finalTest.sh
Ending this.
$ source finalTest.sh
Ending this.
... 異なることに気付くかもしれません 2 つの構文間の動作。;-)