Was ist der Unterschied zwischen dem Ausführen eines Bash-Skripts und dem Sourcen eines Skripts?
Was ist der Unterschied zwischen dem Ausführen eines Bash-Skripts wie A und dem Sourcen eines Bash-Skripts wie B?
A
> ./myscript
B
> source myscript
Was ist der Unterschied zwischen dem Ausführen eines Bash-Skripts wie A und dem Sourcen eines Bash-Skripts wie B?
A
> ./myscript
B
> source myscript
Ein Skript ausgeben führt die Befehle im aktuellen Shell-Prozess aus.
Ausführen eines Skripts führt die Befehle in einem neuen Shell-Prozess aus.
Verwenden Sie source, wenn das Skript die Umgebung in Ihrer aktuell laufenden Shell ändern soll. verwenden Sie andernfalls execute.
Wenn Sie immer noch verwirrt sind, lesen Sie bitte weiter.
Um einige häufige Verwirrungen über die Syntax für execute und die Syntax für source zu klären:
./myscript
Dies wird execute myscript
vorausgesetzt, die Datei ist ausführbar und befindet sich im aktuellen Verzeichnis. Der führende Punkt und Schrägstrich (./
) kennzeichnet das aktuelle Verzeichnis. Dies ist notwendig, da das aktuelle Verzeichnis normalerweise nicht in $PATH
steht (und auch nicht stehen sollte).
myscript
Damit wird myscript
ausgeführt, wenn die Datei ausführbar ist und sich in einem Verzeichnis in $PATH
befindet.
source myscript
Dies wird Quelle myscript
. Die Datei muss nicht ausführbar sein, aber es muss sich um ein gültiges Shell-Skript handeln. Die Datei kann im aktuellen Verzeichnis oder in einem Verzeichnis in $PATH
liegen.
. myscript
Dies wird auch Quelle myscript
. Diese “Schreibweise” ist die offizielle, wie sie von POSIX definiert ist. Die Bash hat source
als Alias für den Punkt definiert.
Betrachten Sie myscript.sh
mit folgendem Inhalt:
#!/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
Bevor wir das Skript ausführen, überprüfen wir zunächst die aktuelle Umgebung:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Die Variable FOO
ist nicht definiert und wir befinden uns im Home-Verzeichnis.
Nun ausführen wir die Datei:
$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Überprüfen Sie die Umgebung erneut:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Die Variable FOO
ist nicht gesetzt und das Arbeitsverzeichnis hat sich nicht geändert.
Die Skriptausgabe zeigt deutlich, dass die Variable gesetzt wurde und das Verzeichnis gewechselt wurde. Die Prüfung danach zeigt, dass die Variable nicht gesetzt und das Verzeichnis nicht geändert wurde. Was ist passiert? Die Änderungen wurden in einer neuen Shell vorgenommen. Die aktuelle Shell hat eine neue Shell erzeugt, um das Skript auszuführen. Das Skript wird in der neuen Shell ausgeführt und alle Änderungen an der Umgebung werden in der neuen Shell wirksam. Nachdem das Skript fertig ist, wird die neue Shell zerstört. Alle Änderungen an der Umgebung in der neuen Shell werden mit der neuen Shell zerstört. Nur der Ausgabetext wird in der aktuellen Shell ausgegeben.
Jetzt sourcen wir die Datei:
$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir
Überprüfen Sie die Umgebung erneut:
$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir
Die Variable FOO ist gesetzt und das Arbeitsverzeichnis hat sich geändert.
Beim Aufruf des Skripts wird keine neue Shell erstellt. Alle Befehle werden in der aktuellen Shell ausgeführt und Änderungen an der Umgebung werden in der aktuellen Shell wirksam.
Beachten Sie, dass in diesem einfachen Beispiel die Ausgabe des Ausführens die gleiche ist wie das Auslagern des Skripts. Dies ist nicht unbedingt immer der Fall.
Betrachten Sie folgendes Skript pid.sh
:
#!/bin/sh
echo $$
(die spezielle Variable $$
expandiert zur PID des aktuell laufenden Shell-Prozesses)
Zuerst die PID der aktuellen Shell ausgeben:
$ echo $$
25009
Das Skript sourcen:
$ source pid.sh
25009
Führen Sie das Skript aus, notieren Sie die PID:
$ ./pid.sh
25011
Erneut Sourcen:
$ source pid.sh
25009
Erneut Ausführen:
$ ./pid.sh
25013
Sie sehen, dass das Sourcen des Skripts im selben Prozess läuft, während das Ausführen des Skripts jedes Mal einen neuen Prozess erzeugt. Dieser neue Prozess ist die neue Shell, die für die Ausführung des Skripts erstellt wurde. Durch das Auslagern des Skripts wird keine neue Shell erstellt und somit bleibt die PID gleich.
Sowohl bei der Beschaffung als auch bei der Ausführung des Skripts werden die Befehle im Skript Zeile für Zeile ausgeführt, als ob Sie diese Befehle Zeile für Zeile von Hand eingeben würden.
Die Unterschiede sind:
Verwenden Sie source, wenn Sie möchten, dass das Skript die Umgebung in Ihrer aktuellen Shell ändert. verwenden Sie ansonsten execute.
Siehe auch:
Wenn Sie ein Skript ausführen, wird es in einem separaten untergeordneten Prozess ausgeführt, d. h. es wird eine separate Instanz der Shell aufgerufen, um das Skript zu verarbeiten. Das bedeutet, dass alle Umgebungsvariablen usw., die im Skript definiert sind, in der übergeordneten (aktuellen) Shell nicht aktualisiert werden können.
Ein Skript auszuliefern bedeutet, dass es von der aktuellen Shell selbst geparst und ausgeführt wird. Es ist so, als ob Sie den Inhalt des Skripts eintippen würden. Aus diesem Grund muss das Skript, das gesourced wird, nicht ausführbar sein. Aber es muss natürlich ausführbar sein, wenn Sie es ausführen wollen.
Wenn Sie Positionsargumente in der aktuellen Shell haben, bleiben diese unverändert.
Wenn ich also eine Datei a.sh
habe, die enthält:
echo a $*
und ich mache:
$ set `date`
$ source ./a.sh
erhalte ich etwas wie:
a Fri Dec 11 07:34:17 PST 2009
dagegen:
$ set `date`
$ ./a.sh
liefert mir:
a
Hoffentlich hilft das.
sourcing ist im Wesentlichen dasselbe wie das Eintippen jeder Zeile des Skripts an der Eingabeaufforderung, eine nach der anderen…
Die Ausführung startet einen neuen Prozess und führt dann jede Zeile des Skripts aus, wobei die aktuelle Umgebung nur durch das verändert wird, was sie zurückgibt.
Zusätzlich zu den obigen Ausführungen erfordert die Ausführung des Skripts als ./myscript
die Ausführungsberechtigung für die Datei myscript, während für das Sourcen keine Ausführungsberechtigung erforderlich ist. Deshalb wird chmod +x myscript
nicht vor source myscript
benötigt.
Beim Sourcen erhalten Sie alle zusätzlichen Variablen, die im Skript definiert sind.
Wenn Sie also Configs oder Funktionsdefinitionen haben, sollten Sie quellen und nicht ausführen. Ausführen ist unabhängig von der übergeordneten Umgebung.
Der Befehl source
führt das angegebene Skript (Ausführungserlaubnis ist nicht zwingend ) in der aktuellen Shell-Umgebung aus, während ./
das angegebene ausführbare Skript in einer neuen Shell ausführt.
Sehen Sie sich auch diese Antwort als Beispiel an: https://superuser.com/a/894748/432100