![Skriptfunktionsaufruf: Funktion vs. $(Funktion)](https://rvso.com/image/192236/Skriptfunktionsaufruf%3A%20Funktion%20vs.%20%24(Funktion).png)
Der Einfachheit halber verweisen wir auf den folgenden Code.
#!/bin/bash
number=7
function doSomething() {
number=8
}
doSomething
echo "$number"
Es druckt 8
.
Aber mit:
#!/bin/bash
number=7
function doSomething() {
number=8
}
$(doSomething)
echo "$number"
Es druckt 7
.
Ich habe folgende Fragen:
- Was sind dietechnische Namenfür jeden?, ich meine
functioncall
und$(functioncall)
- Wie funktioniert jeder Ansatz? Es scheint, dass ersterer die Variablen außerhalb der Funktion selbst berücksichtigt (beeinflusst), letzterer nicht
- Wenn es zwingend erforderlich ist, einen Ansatz dem anderen vorzuziehen (meistens geht es natürlich um Leistungsprobleme, falls es welche gibt), sind andere Gründe willkommen.
Antwort1
Sie erleben die Feinheiten der Befehlssubstitution.
Der Anruf
doSomething
ist ein einfacher Funktionsaufruf. Er führt die Funktion aus, so als ob Sie die Befehle der Funktion kopiert und an die Stelle eingefügt hätten, an der Sie sie aufrufen. Dabei überschreibt er die Variable number
mit dem neuen Wert 8
.
Der Anruf
$(doSomething)
auf der anderen Seite ist einBefehlsersetzung. Es ist dazu gedacht, die Funktion auszuführen undgibt den Inhalt der ausgegebenen Funktion zurück stdout
. Es wird normalerweise nicht "standalone" verwendet, sondern in Variablenzuweisungen, z. B.
os_type=$(uname)
Dadurch wird der Befehl ausgeführt uname
, der auf einem Linux-System auf der Konsole ausgegeben wird Linux
, und das Ergebnis wird in der Shell-Variable gespeichert os_type
. Daher ist es nicht sinnvoll, einen Befehlsersatz mit einem Befehl oder einer Funktion zu verwenden, die nichts ausgibt, wie Ihr doSomething
. Da der Ersatz $(doSomething)
im Grunde ein Platzhalter für die Ausgabe von ist doSomething
, besteht der einzige Grund, warum Sie dort keinen Skriptfehler erhalten, darin, dass Ihre Funktion nichts ausgibt. Hätten Sie beispielsweise angegeben,
$(uname)
anstatt
$(doSomething)
Ihre Shell hätte versucht, den Befehl auszuführen Linux
und eine
Linux: No such file or directory
Fehler (1) .
Der Schlüssel zum Verständnis des beobachteten Effekts ist, dass bei einer Befehlssubstitutionder Befehl wird in einer Subshell ausgeführt, d. h. alle an Variablen vorgenommenen Änderungen werden nicht an die Shell zurückpropagiert, in der Sie das Hauptskript ausführen. Während es intern die Befehle von ausführt doSomething
und eine Variable number
auf setzt 8
, geschieht dies in seinem eigenen Shell-Prozess, der nichts mit dem Shell-Prozess zu tun hat, der Ihr Skript ausführt (abgesehen davon, dass es stdout
abgerufen wird), und kann daher die Variable, number
die Sie im Hauptskript verwendet haben, nicht ändern.
Weitere Informationen finden Sie unter
hier auf dieser Site oder
für mehr Übersicht.
(1) Andererseits bedeutet dies, dass Sie durch eine Befehlsersetzung einen Befehl ausführen können, dessen Namen Sie beim Schreiben des Skripts noch nicht kennen, den Sie aber durch Ausführen eines anderen, Ihnen bekannten Befehls herausfinden können.