69

shとはどう違いsourceますか?

source: source filename [arguments]
    Read and execute commands from FILENAME and return.  The pathnames
    in $PATH are used to find the directory containing FILENAME.  If any
    ARGUMENTS are supplied, they become the positional parameters when
    FILENAME is executed.

そしてのためにman sh

NAME
       bash - GNU Bourne-Again SHell

SYNOPSIS
       bash [options] [file]

COPYRIGHT
       Bash is Copyright (C) 1989-2004 by the Free Software Foundation, Inc.

DESCRIPTION
       Bash  is  an sh-compatible command language interpreter that executes commands read from the standard input or from a file.  Bash also incorporates
       useful features from the Korn and C shells (ksh and csh).

       Bash is intended to be a conformant implementation of the IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2).
4

5 に答える 5

97

sourceor .(一方は他方のエイリアスです。cmdsourceは POSIX ではありません - bashismのようなものです) を呼び出すと現在のbash プロセスにbash スクリプトをロードして実行します。だからあなたはできる

  • ソーススクリプトに設定された変数を読み取り、
  • その中で定義された関数を使用します。
  • スクリプトがこれを行う場合は、フォークやサブプロセスも実行します。

を呼び出すと、通常は へのシンボリック リンクであるの新しいセッションを実行するフォーク(サブプロセスまたは子sh)が開始されます。この場合、サブスクリプトによって設定された環境変数は、サブスクリプトが終了すると削除されます。/bin/shbash

注意:別のシェル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に基づく補完あり)。

実行レベル$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 ( $$== process Id ) はSID ( session 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.\nsleep 1;exit 0\n' >finalTest.sh

$ bash finalTest.sh 
Ending this.

$ source finalTest.sh
Ending this.

... 2 つの構文の動作が異なることに気付くかもしれません。;-)

于 2012-12-09T10:13:05.987 に答える
14

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

したがってsource、ファイルfooを実行するcdと、ソース シェル (ターミナル内のインタラクティブ シェルなど) が影響を受けます (現在のディレクトリが変更されます)。

を実行sh foocdてもソーシングシェルには影響せず、新しく作成されたshプロセスのみが実行されますfoo

高度な Bash スクリプト作成ガイドをお読みください。

この違いは Linux に固有のものではありません。すべての Posix 実装にはそれがあります。

于 2012-12-09T10:09:45.950 に答える
5

他の人が述べたように、実行すると、プロセスが終了した後、シェル環境にsh test.sh加えられた変更は保持されません。test.sh

ただし、エクスポートされていない環境の要素 (変数、エイリアス、シェル関数など) はtest.sh、サブプロセスとして (つまり を使用してsh test.sh) 実行されると、コードで使用できないことにも注意してください。

例えば:

$ cat > test.sh
echo $foo
$ foo=bar
$ sh test.sh
$ . test.sh
bar

例 2:

lap@my-ThinkPad:~$ cat test.sh
#!/bin/sh
cd /etc
lap@my-ThinkPad:~$ sh test.sh 
lap@my-ThinkPad:~$ pwd
/home/savoury
lap@my-ThinkPad:~$ source test.sh 
lap@my-ThinkPad:/etc$ pwd
/etc
lap@my-ThinkPad:/etc$ 
于 2015-03-14T17:20:35.677 に答える
1

sh コマンドでプログラムを実行すると、次のようになります。

  • 端末は sh または Bourne Shell を使用してプログラムを実行します。
  • Bash はそれ自体の正確なコピーを作成するため、新しいプロセスが作成されます。この子プロセスの環境は親プロセスと同じですが、プロセス ID 番号だけが異なります。(このプロセスは forking と呼ばれます)
  • 実行するには実行権限が必要です(フォークしているため)

source コマンドを使用する場合:

  • デフォルトのインタープリターでプログラムを実行します
  • 現在の端末でプロセスを実行します(技術的には *nix コマンドが解釈されます)
  • プログラムは現在の端末で実行されるため、実行許可を与える必要はありません
于 2013-02-27T05:27:53.603 に答える