Ich lerne Shell-Scripting mit Bash und muss den Unterschied zwischen (...)und kennen {...}. Wie wählt man beim Schreiben eines Drehbuchs zwischen den beiden?
Wenn sich die Nebenwirkungen der Befehlsliste auf Ihre aktuelle Shell auswirken sollen , verwenden {...}
Sie Wenn Sie alle Nebenwirkungen verwerfen möchten, verwenden Sie(...)
Zum Beispiel könnte ich eine Subshell verwenden, wenn ich:
möchte $IFSfür ein paar Befehle ändern , aber ich möchte nicht $IFSglobal für die aktuelle Shell ändern
cdirgendwo, aber ich möchte das $PWDfür die aktuelle Shell nicht ändern
Es ist zu beachten, dass Klammern in einer Funktionsdefinition verwendet werden können:
normale Verwendung: geschweifte Klammern: Funktionskörper wird in der aktuellen Shell ausgeführt; Nebenwirkungen bleiben nach Beendigung der Funktion bestehen
Nach vielen Jahren der Shell-Entwicklung wusste ich nicht, dass Sie Klammern verwenden können, um Funktionen in Subshells auszuführen. Was für eine großartige Idee, den globalen Namespace nicht zu verschmutzen!
l0b0
7
Die Verwendung des localSchlüsselworts trägt wesentlich dazu bei, diese Verschmutzung zu beseitigen.
Glenn Jackman
2
Ja, aber Sie müssen daran denken, jede Variable local zu deklarieren, und der Code wird übersichtlich.
08.
4
Tipp: Wenn Sie nebenwirkungsfreie Funktionen wünschen, aber die ungewöhnliche Syntax der Funktionsdeklaration vermeiden möchten (die den Code-Editoren möglicherweise nicht bekannt ist), verwenden Sie statt der Deklaration nur Klammern beim Funktionsaufruf:pwd; (count_tmp); pwd;
Juve
2
zur Shell ... foo () (:;) ist äquivalent zu foo () {(:;); } So meldet es sich, wenn Sie fragen!
Wenn Sie eine Befehlsliste in Klammern setzen, wird eine Subshell-Umgebung erstellt und alle Befehle in der Liste in dieser Subshell ausgeführt. Da die Liste in einer Subshell ausgeführt wird, bleiben die Variablenzuweisungen nach Abschluss der Subshell nicht wirksam.
{}
{ list;}
Wenn Sie eine Befehlsliste in geschweifte Klammern setzen, wird die Liste im aktuellen Shell-Kontext ausgeführt. Es wird keine Subshell erstellt. Die folgende Liste mit Semikolon (oder Zeilenvorschub) ist erforderlich.
Code in '{}' wird im aktuellen Thread / Prozess / in der aktuellen Umgebung ausgeführt und Änderungen werden beibehalten. Um es kurz zu machen, der Code wird im aktuellen Bereich ausgeführt.
Code in '()' wird in einem separaten untergeordneten Prozess von bash ausgeführt, der nach der Ausführung verworfen wird. Dieser untergeordnete Prozess wird oft als Sub-Shell bezeichnet und kann als neuer, kindlicher Bereich betrachtet werden.
Beachten Sie, dass im ersten Beispiel mit '{}' die Variable auch nach dem Schließen von '}' noch gesetzt ist, während im Beispiel mit '()' die Variable nicht außerhalb des Bereichs von '()' gesetzt ist.
(...)werden verwendet, um Code in einer Sub-Shell auszuführen. Code, der bei der Ausführung {...}verwendet wurde, wird in einer Sub-Shell nicht verwendet.
Antworten:
Wenn sich die Nebenwirkungen der Befehlsliste auf Ihre aktuelle Shell auswirken sollen , verwenden
{...}
Sie Wenn Sie alle Nebenwirkungen verwerfen möchten, verwenden Sie
(...)
Zum Beispiel könnte ich eine Subshell verwenden, wenn ich:
$IFS
für ein paar Befehle ändern , aber ich möchte nicht$IFS
global für die aktuelle Shell änderncd
irgendwo, aber ich möchte das$PWD
für die aktuelle Shell nicht ändernEs ist zu beachten, dass Klammern in einer Funktionsdefinition verwendet werden können:
normale Verwendung: geschweifte Klammern: Funktionskörper wird in der aktuellen Shell ausgeführt; Nebenwirkungen bleiben nach Beendigung der Funktion bestehen
ungewöhnliche Verwendung: Klammern: Funktionskörper wird in einer Subshell ausgeführt; Nebenwirkungen verschwinden, wenn die Subshell beendet wird
Dokumentation
quelle
local
Schlüsselworts trägt wesentlich dazu bei, diese Verschmutzung zu beseitigen.pwd; (count_tmp); pwd;
Aus der offiziellen Bash-Dokumentation :
quelle
Code in '{}' wird im aktuellen Thread / Prozess / in der aktuellen Umgebung ausgeführt und Änderungen werden beibehalten. Um es kurz zu machen, der Code wird im aktuellen Bereich ausgeführt.
Code in '()' wird in einem separaten untergeordneten Prozess von bash ausgeführt, der nach der Ausführung verworfen wird. Dieser untergeordnete Prozess wird oft als Sub-Shell bezeichnet und kann als neuer, kindlicher Bereich betrachtet werden.
Betrachten Sie als Beispiel Folgendes ...
Beachten Sie, dass im ersten Beispiel mit '{}' die Variable auch nach dem Schließen von '}' noch gesetzt ist, während im Beispiel mit '()' die Variable nicht außerhalb des Bereichs von '()' gesetzt ist.
quelle
(...)
werden verwendet, um Code in einer Sub-Shell auszuführen. Code, der bei der Ausführung{...}
verwendet wurde, wird in einer Sub-Shell nicht verwendet.quelle