Studiuję skryptowanie powłoki za pomocą bash i muszę znać różnicę między (...)
i {...}
. Jak wybierać między nimi podczas pisania skryptu?
Studiuję skryptowanie powłoki za pomocą bash i muszę znać różnicę między (...)
i {...}
. Jak wybierać między nimi podczas pisania skryptu?
Odpowiedzi:
Jeśli chcesz, aby skutki uboczne z listy poleceń wpływały na twoją bieżącą powłokę, użyj {...}
Jeśli chcesz odrzucić jakiekolwiek skutki uboczne, użyj(...)
Na przykład mogę użyć podpowłoki, jeśli:
$IFS
kilka poleceń, ale nie chcę zmieniać $IFS
globalnie dla bieżącej powłokicd
gdzieś, ale nie chcę zmieniać $PWD
bieżącej powłokiWarto zauważyć, że w definicji funkcji można użyć nawiasów:
normalne użycie: nawiasy klamrowe: ciało funkcji wykonuje się w bieżącej powłoce; działania niepożądane pozostają po zakończeniu funkcji
$ count_tmp() { cd /tmp; files=(*); echo "${#files[@]}"; }
$ pwd; count_tmp; pwd
/home/jackman
11
/tmp
$ echo "${#files[@]}"
11
nietypowe użycie: nawiasy: ciało funkcji wykonuje się w podpowłoce; efekty uboczne znikają po wyjściu podpowłoki
$ cd ; unset files
$ count_tmp() (cd /tmp; files=(*); echo "${#files[@]}")
$ pwd; count_tmp; pwd
/home/jackman
11
/home/jackman
$ echo "${#files[@]}"
0
local
słowa kluczowego ma długą drogę do usunięcia tego zanieczyszczenia.
pwd; (count_tmp); pwd;
Z oficjalnej dokumentacji bash :
()
( list )
Umieszczenie listy poleceń między nawiasami powoduje utworzenie środowiska podpowłoki i wykonanie każdego z poleceń na liście w tej podpowłoce. Ponieważ lista jest wykonywana w podpowłoce, przypisania zmiennych nie pozostają aktywne po zakończeniu podpowłoki.
{}
{ list; }
Umieszczenie listy poleceń między nawiasami klamrowymi powoduje, że lista jest wykonywana w bieżącym kontekście powłoki. Nie jest tworzona podpowłoka. Wymagana jest następująca lista średników (lub znaków nowej linii).
Kod w „{}” jest wykonywany w bieżącym wątku / procesie / środowisku, a zmiany są zachowywane, mówiąc bardziej zwięźle, kod jest uruchamiany w bieżącym zakresie.
Kod w „()” jest uruchamiany w osobnym, potomnym procesie bash, który jest odrzucany po wykonaniu. Ten proces potomny jest często nazywany podpowłoką i można go traktować jako nowy zakres potomny.
Jako przykład rozważ następujące ...
~ # { test_var=test }
~ # echo $test_var
test
~ # ( test_var2=test2 )
~ # echo $test_var2
~ #
Zauważ, że w pierwszym przykładzie z „{}” zmienna jest nadal ustawiana nawet po zamknięciu „}”, podczas gdy w przykładzie z „()” zmienna nie jest ustawiona poza zakresem „()”.
(...)
są używane do uruchamiania kodu w podpowłoce. Użyty kod {...}
poniżej nie będzie używany w podpowłoce.