Antworten:
Durch die Beschaffung eines Skripts werden die Befehle im aktuellen Shell-Prozess ausgeführt.
Durch Ausführen eines Skripts werden die Befehle in einem neuen Shell-Prozess ausgeführt.
Verwenden Sie source, wenn das Skript die Umgebung in Ihrer aktuell ausgeführten Shell ändern soll. Verwenden Sie Execute ansonsten.
Wenn Sie immer noch verwirrt sind, lesen Sie bitte weiter.
Um einige allgemeine Unklarheiten über die auszuführende Syntax und die zu quellende Syntax zu klären:
./myscript
Dies wird ausgeführt, myscript
sofern die Datei ausführbar ist und sich im aktuellen Verzeichnis befindet. Der führende Punkt und Schrägstrich ( ./
) kennzeichnet das aktuelle Verzeichnis. Dies ist notwendig, da das aktuelle Verzeichnis normalerweise nicht in ist (und normalerweise nicht sein sollte) $PATH
.
myscript
Dies wird ausgeführt, myscript
wenn die Datei ausführbar ist und sich in einem Verzeichnis in befindet $PATH
.
source myscript
Dies wird Quelle myscript
. Die Datei muss nicht ausführbar sein, es muss sich jedoch um ein gültiges Shell-Skript handeln. Die Datei kann sich im aktuellen Verzeichnis oder in einem Verzeichnis in befinden $PATH
.
. myscript
Dies wird auch Quelle myscript
. Diese "Schreibweise" ist die offizielle, wie sie von POSIX definiert wurde . Bash wird source
als Alias für den Punkt definiert.
Bedenken 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 zuerst ausführen, überprüfen wir die aktuelle Umgebung:
$ env | grep FOO
$ echo $PWD
/home/lesmana
Die Variable FOO
ist nicht definiert und wir befinden uns im Home-Verzeichnis.
Jetzt sind wir ausführen , 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 und das Verzeichnis geändert wurde. Die anschließende Prüfung 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. Nach Abschluss des Skripts wird die neue Shell zerstört. Alle Änderungen an der Umgebung in der neuen Shell werden mit der neuen Shell zerstört. In der aktuellen Shell wird nur der Ausgabetext gedruckt.
Nun wir beziehen 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.
Durch die Beschaffung 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 der Ausführung der Ausgabe des Skripts entspricht. Dies ist nicht unbedingt immer der Fall.
Betrachten Sie folgendes Skript pid.sh
:
#!/bin/sh
echo $$
(Die Spezialvariable wird $$
auf die PID des aktuell ausgeführten Shell-Prozesses erweitert.)
Drucken Sie zuerst die PID der aktuellen Shell:
$ echo $$
25009
Quell das Skript:
$ source pid.sh
25009
Führen Sie das Skript aus und beachten Sie die PID:
$ ./pid.sh
25011
Nochmals Quelle:
$ source pid.sh
25009
Erneut ausführen:
$ ./pid.sh
25013
Sie können sehen, dass die Beschaffung des Skripts im selben Prozess ausgeführt wird, während die Ausführung des Skripts jedes Mal einen neuen Prozess erstellt. Dieser neue Prozess ist die neue Shell, die für die Ausführung des Skripts erstellt wurde. Durch die Beschaffung des Skripts wird keine neue Shell erstellt, und daher bleibt die PID gleich.
Sowohl beim Aufrufen als auch beim Ausführen des Skripts werden die Befehle im Skript zeilenweise ausgeführt, als ob Sie diese Befehle von Hand zeilenweise eingegeben hätten.
Die Unterschiede sind:
Verwenden Sie source, wenn das Skript die Umgebung in Ihrer aktuell ausgeführten Shell ändern soll. Verwenden Sie Execute ansonsten.
Siehe auch:
source myscript.sh
und . myscript.sh
?
Beim Ausführen eines Skripts wird es in einem separaten untergeordneten Prozess ausgeführt, dh, es wird eine separate Instanz der Shell aufgerufen, um das Skript zu verarbeiten. Dies bedeutet, dass Umgebungsvariablen usw., die im Skript definiert sind, nicht in der übergeordneten (aktuellen) Shell aktualisiert werden können .
Das Beschaffen eines Skripts bedeutet, dass es von der aktuellen Shell selbst analysiert und ausgeführt wird. Es ist, als ob Sie den Inhalt des Skripts eingegeben hätten. Aus diesem Grund muss das zu beschaffende Skript nicht ausführbar sein. Aber es muss ausführbar sein, wenn Sie es natürlich ausführen.
Wenn Sie in der aktuellen Shell Positionsargumente haben, bleiben diese unverändert.
Also, wenn ich eine Datei habe, die a.sh
enthält:
echo a $*
und ich mache:
$ set `date`
$ source ./a.sh
Ich bekomme so etwas wie:
a Fri Dec 11 07:34:17 PST 2009
Wohingegen:
$ set `date`
$ ./a.sh
gibt mir:
a
Ich hoffe, das hilft.
Sourcing ist im Wesentlichen dasselbe wie das Eingeben jeder einzelnen Zeile des Skripts an der Eingabeaufforderung ...
Die Ausführung startet einen neuen Prozess und führt dann jede Zeile des Skripts aus. Dabei wird nur die aktuelle Umgebung anhand der zurückgegebenen Umgebung geändert.
Darüber hinaus ./myscript
erfordert die Ausführung des Skripts als Ausführungsberechtigung für die Datei myscript, während für das Sourcing keine Ausführungsberechtigung erforderlich ist. Deshalb ist chmod +x myscript
das vorher nicht erforderlichsource myscript
bash myscript
.
Bei der Beschaffung erhalten Sie alle zusätzlichen Variablen, die im Skript definiert sind.
Wenn Sie also Konfigurations- oder Funktionsdefinitionen haben, sollten Sie diese als Quelle verwenden und nicht ausführen. Die Hinrichtungen sind unabhängig von der Umgebung der Eltern.
Wenn ich mich wieder richtig erinnere, wird beim Ausführen des Skripts die ausführbare Datei in der #!
Zeile mit der Skriptdatei als Argument ausgeführt (normalerweise wird eine neue Shell gestartet und das Skript wird wie bei "" in die neue Shell geladen #!/bin/sh
).
Durch die Verwendung des Skripts wird jede Zeile in Ihrer aktuellen Shell-Umgebung ausgeführt. Dies ist nützlich, um Ihre aktuelle Shell zu ändern (z. B. um Shell-Funktionen zu definieren und Umgebungsvariablen zu exportieren).
source
Der Befehl führt das bereitgestellte Skript in der aktuellen Shell-Umgebung aus (ausführbare Berechtigungen sind nicht erforderlich ) , während das bereitgestellte ausführbare Skript in einer neuen Shell ausgeführt wird../
Überprüfen Sie auch diese Antwort, zum Beispiel: https://superuser.com/a/894748/432100