GNU/Linux >> Linux の 問題 >  >> Linux

`sh` と `source` の使用の違いは何ですか?

主な違いは、異なるプロセスで実行されることです。

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 つの構文間の動作。;-)


Linux
  1. [[$ a ==Z*]]と[$a==Z *]の違いは?

  2. insmodとmodprobeの違いは何ですか

  3. Cのstrtok_rとstrtok_sの違いは何ですか?

  1. adduser と useradd の違いは何ですか?

  2. $(CC) と $CC の違いは何ですか?

  3. unlink と rm の違いは何ですか?

  1. InnoDBとMyISAMの違いは何ですか?

  2. Gitスイッチとチェックアウトの違いは何ですか?

  3. php-fpmのupstreamとlocationの使用の違いは何ですか?