GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Was ist der Unterschied zwischen der Ausführung eines Bash-Skripts und dessen Beschaffung?

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.


Linux
  1. Der Unterschied zwischen Sourcing (‚.‘ oder ‚source‘) und dem Ausführen einer Datei in Bash?

  2. Wie liest man das gesamte Shell-Skript, bevor man es ausführt?

  3. Was ist der Unterschied zwischen nohup und kaufmännischem Und?

  4. Was ist der Unterschied zwischen #!/usr/bin/env bash und #!/usr/bin/bash?

  5. Was ist der Unterschied zwischen fsck und e2fsck?

Was ist der Unterschied zwischen InnoDB und MyISAM?

Was ist der Unterschied zwischen Linux und Unix?

Was ist der Unterschied zwischen Login- und Non-Login-Shell

Was ist ein Hypervisor? Was ist der Unterschied zwischen Typ 1 und 2?

Was ist der Unterschied zwischen Curl und Wget?

Was ist der Unterschied zwischen unlink und rm?