Ich lerne Shell-Scripting mit Bash und muss den Unterschied zwischen (...)
und kennen {...}
. Wie wählt man beim Schreiben eines Drehbuchs zwischen den beiden?
Ich lerne Shell-Scripting mit Bash und muss den Unterschied zwischen (...)
und kennen {...}
. Wie wählt man beim Schreiben eines Drehbuchs zwischen den beiden?
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
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
ungewöhnliche Verwendung: Klammern: Funktionskörper wird in einer Subshell ausgeführt; Nebenwirkungen verschwinden, wenn die Subshell beendet wird
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
local
Schlüsselworts trägt wesentlich dazu bei, diese Verschmutzung zu beseitigen.
pwd; (count_tmp); pwd;
Aus der offiziellen Bash-Dokumentation :
()
( list )
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.
Betrachten Sie als Beispiel Folgendes ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
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.