Beschaffung ein Skript führt die Befehle im aktuellen aus Shell-Prozess.
Ausführen ein Skript führt die Befehle in einem neuen aus Shell-Prozess.
Verwenden Sie source, wenn Sie möchten, dass das Skript die Umgebung in Ihrer aktuell ausgeführten Shell ändert. Verwenden Sie andernfalls Ausführen.
Die "Umgebung" sind Dinge wie das aktuelle Arbeitsverzeichnis und Umgebungsvariablen. auch Shell-Einstellungen (ua History- und Completion-Features). es gibt noch mehr, aber das sind die sichtbarsten.
Wenn Sie mehr Details wünschen, lesen Sie bitte weiter.
Terminologie
Um einige häufige Verwirrung über die auszuführende und die zu beschaffende Syntax zu klären:
./myscript
Dies wird ausgeführt myscript
vorausgesetzt, die Datei ist ausführbar und befindet sich im aktuellen Verzeichnis. Der führende Punkt und Schrägstrich (./
) bezeichnet das aktuelle Verzeichnis. Dies ist notwendig, da das aktuelle Verzeichnis normalerweise nicht in $PATH
liegt (und normalerweise nicht sein sollte). .
myscript
Dies wird ausgeführt myscript
wenn die Datei ausführbar ist und sich in einem Verzeichnis in $PATH
befindet .
source myscript
Dies wird source myscript
. Die Datei muss nicht ausführbar sein, aber es muss sich um ein gültiges Shell-Skript handeln. Die Datei kann sich im aktuellen Verzeichnis oder in einem Verzeichnis in $PATH
befinden .
. myscript
Dies wird auch source myscript
. Diese "Schreibweise" ist die offizielle, wie von POSIX definiert. Bash hat source
definiert als Alias für den Punkt.
und der Vollständigkeit halber:
exec myscript
Dadurch wird die aktuelle Shell beendet und dann myscript anstelle der beendeten Shell ausgeführt. Das bedeutet, wenn myscript fertig ist, gibt es keine alte Shell, zu der man zurückkehren kann. exec
ist mächtig, wird aber selten benötigt.
Ich habe am Ende einige Links für weitere Informationen zu diesen Themen eingefügt.
Vorführung
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.
Jetzt exekutieren 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 und das Verzeichnis geändert wurde. Die Prüfung danach zeigt, dass die Variable nicht gesetzt ist und das Verzeichnis nicht geändert wurde. Was ist passiert? Die Änderungen wurden in einem neuen vorgenommen Hülse. Der Strom Shell hat eine neue hervorgebracht Shell, 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. In der aktuellen Shell wird nur der Ausgabetext 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.
Durch das Sourcing 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 dieselbe ist wie die Beschaffung des Skripts. Dies ist nicht unbedingt immer der Fall.
Eine weitere Demonstration
Betrachten Sie das folgende Skript pid.sh
:
#!/bin/sh
echo $$
(die spezielle Variable $$
wird zur PID des aktuell laufenden Shell-Prozesses erweitert)
Geben Sie zuerst die PID der aktuellen Shell aus:
$ echo $$
25009
Quelle des Skripts:
$ source pid.sh
25009
Führen Sie das Skript aus, notieren Sie sich die PID:
$ ./pid.sh
25011
Quelle nochmal:
$ source pid.sh
25009
Erneut ausführen:
$ ./pid.sh
25013
Sie können sehen, dass das Sourcing 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 das Neue Shell, die für die Ausführung des Skripts erstellt wurde. Das Sourcing des Skripts erzeugt keine neue Shell und somit bleibt die PID gleich.
Zusammenfassung
Sowohl das Quellen als auch das Ausführen des Skripts führen die Befehle im Skript Zeile für Zeile aus, als ob Sie diese Befehle Zeile für Zeile von Hand eingegeben hätten.
Die Unterschiede sind:
- Wenn Sie ausführen das Skript, das Sie öffnen, neu Shell, geben Sie die Befehle in die neue Shell ein, kopieren Sie die Ausgabe zurück in Ihre aktuelle Shell und schließen Sie dann die neue Shell. Alle Änderungen an der Umgebung werden nur in der neuen Shell wirksam und gehen verloren, sobald die neue Shell geschlossen wird.
- Wenn Sie sourcen das Skript, in das Sie die Befehle in Ihrem aktuellen eingeben Hülse. Alle Änderungen an der Umgebung werden wirksam und bleiben in Ihrer aktuellen Shell.
Verwenden Sie source, wenn Sie möchten, dass das Skript die Umgebung in Ihrer aktuell ausgeführten Shell ändert. Verwenden Sie andernfalls Ausführen.
Siehe auch:
- https://stackoverflow.com/questions/6331075/warum-braucht-du-punkt-slash-before-script-name-to-run-it-in-bash
- https://askubuntu.com/questions/182012/gibt-es-nach-allem-einen-unterschied-zwischen-und-quelle-in-bash
- https://stackoverflow.com/questions/18351198/what-are-the-uses-of-the-exec-command-in-shell-scripts
Das Ausführen eines Skripts führt es in einem separaten untergeordneten Prozess aus, d. h. eine separate Instanz der Shell wird aufgerufen, um das Skript zu verarbeiten. Dies bedeutet, dass alle im Skript definierten Umgebungsvariablen usw. nicht können in der übergeordneten (aktuellen) Shell aktualisiert werden.
Die Beschaffung eines Skripts bedeutet, dass es von der aktuellen Shell selbst analysiert und ausgeführt wird. Es ist, als ob Sie den Inhalt des Skripts eingetippt hätten. Aus diesem Grund muss das bezogene Skript nicht ausführbar sein. Aber es muss natürlich ausführbar sein, wenn Sie es ausführen.
Wenn Sie Positionsargumente in der aktuellen Shell haben, bleiben sie unverändert.
Wenn ich also eine Datei a.sh
habe 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
Wobei:
$ set `date`
$ ./a.sh
gibt mir:
a
Hoffe das hilft.
Sourcing ist im Wesentlichen dasselbe wie das Eingeben jeder Zeile des Skripts nacheinander an der Eingabeaufforderung ...
Die Ausführung startet einen neuen Prozess und führt dann jede Zeile des Skripts aus, wobei die aktuelle Umgebung nur durch das geändert wird, was sie zurückgibt.