Jestem zdezorientowany używaniem nawiasów, nawiasów, nawiasów klamrowych w Bash, a także różnicą między ich podwójnymi lub pojedynczymi formami. Czy jest jasne wytłumaczenie?
W Basha, test
i [
są powłoki builtins.
Podwójny uchwyt , który jest powłoką Hasło umożliwia dodatkową funkcjonalność. Na przykład, można użyć &&
i ||
zamiast -a
a -o
i tam regularne operator dopasowanie wyraz =~
.
Ponadto w prostym teście nawiasy kwadratowe wydają się oceniać znacznie szybciej niż pojedyncze.
$ time for ((i=0; i<10000000; i++)); do [[ "$i" = 1000 ]]; done
real 0m24.548s
user 0m24.337s
sys 0m0.036s
$ time for ((i=0; i<10000000; i++)); do [ "$i" = 1000 ]; done
real 0m33.478s
user 0m33.478s
sys 0m0.000s
Nawiasy klamrowe oprócz ograniczania nazwy zmiennej służą do rozszerzania parametrów, dzięki czemu można wykonywać następujące czynności:
Obetnij zawartość zmiennej
$ var="abcde"; echo ${var%d*}
abc
Dokonaj podstawień podobnych do sed
$ var="abcde"; echo ${var/de/12}
abc12
Użyj wartości domyślnej
$ default="hello"; unset var; echo ${var:-$default}
hello
i kilka innych
Ponadto rozszerzenia nawiasów tworzą listy ciągów, które są zazwyczaj iterowane w pętlach:
$ echo f{oo,ee,a}d
food feed fad
$ mv error.log{,.OLD}
(error.log is renamed to error.log.OLD because the brace expression
expands to "mv error.log error.log.OLD")
$ for num in {000..2}; do echo "$num"; done
000
001
002
$ echo {00..8..2}
00 02 04 06 08
$ echo {D..T..4}
D H L P T
Pamiętaj, że wiodące funkcje zerowania i przyrostu nie były dostępne przed Bash 4.
Dzięki gboffi za przypomnienie mi o rozszerzeniach aparatu.
Podwójne nawiasy są używane do operacji arytmetycznych :
((a++))
((meaning = 42))
for ((i=0; i<10; i++))
echo $((a + b + (14 * c)))
i pozwalają ominąć znaki dolara na zmiennych całkowitych i tablicowych oraz zawierać spacje wokół operatorów dla czytelności.
Pojedyncze nawiasy klamrowe są również używane dla indeksów tablicowych :
array[4]="hello"
element=${array[index]}
Nawiasy klamrowe są wymagane dla (większości / wszystkich?) Odniesień do tablicy po prawej stronie.
Komentarz ephemienta przypomniał mi, że nawiasy są również używane do podpowłoki. I że są one używane do tworzenia tablic.
array=(1 2 3)
echo ${array[1]}
2
:
.$[expression]
:; to jest stara, przestarzała składnia arytmetyczna wyrażenia dla nowszej, preferowanej składni:$((expression))
bash
jest tworzenie sekwencji, jak wspomniano poniżej peryferyjnie ( stackoverflow.com/a/8552128/2749397 ) Chciałbym skomentować nieco tę funkcję (o której nie wspomniałeś ;-) m pozwalając sobie na użycie najczęściej głosowanej odpowiedzi jako pojazdu ... Dwa przykłady literałów sekwencji:echo {01..12}
->01 02 03 04 05 06 07 08 09 10 11 12
(zwróć uwagę na początkowe zero);echo {C..Q}
->C D E F G H I J K L M N O P Q
. Jego głównym zastosowaniem są pętle, np.for cnt in {01..12} ; do ... ${cnt} ... ; done
echo {01..12..2}
-> „01 03 05 07 09 11”. Dzięki za przypomnienie o sekwencjach. Dodam to do mojej odpowiedzi.Pojedynczy nawias kwadratowy (
[
) zwykle wywołuje program o nazwie[
;man test
lubman [
po więcej informacji. Przykład:Podwójny nawias (
[[
) robi to samo (w zasadzie) jak pojedynczy nawias, ale jest wbudowany w bash.Nawiasy (
()
) służą do tworzenia podpowłoki. Na przykład:Jak widać, podpowłoka umożliwia wykonywanie operacji bez wpływu na środowisko bieżącej powłoki.
(a) Aparat ortodontyczny (
{}
) służą do jednoznacznej identyfikacji zmiennych. Przykład:(b) Nawiasy klamrowe są również używane do wykonywania sekwencji poleceń w bieżącym kontekście powłoki, np
Istnieje jednak subtelna różnica składniowa z
( )
(patrz odniesienie do bash ); zasadniczo, średnik;
po ostatnim poleceniu w szelki jest koniecznością, a szelki{
,}
muszą być otoczone spacjami.źródło
[
tak naprawdę jest wbudowany w Bash, ale powinien działać jak/bin/[
w przeciwieństwie do[[
wbudowanego.[[
ma różne funkcje, takie jak bardziej logiczne operacje i różne role cytowania. Dodatkowo: pojedyncze nawiasy są również używane do tablic, podstawiania procesów i rozszerzonych globów; w arytmetyce stosowane są podwójne nawiasy; nawiasy klamrowe{}
są używane do grupowania poleceń lub mnóstwa typów interpretacji parametrów, interpretacji nawiasów lub interpretacji sekwencji. Jestem pewien, że przegapiłem też inne zastosowania ...if [ $VARIABLE == abcdef ]
to bazizm, którego - choć działa - prawdopodobnie należy go unikać; jawnie użyj bash (if [[ ...==...]]
) lub wyjaśnij, że używasz bardziej tradycyjnej metody warunkowej (if [ "$VARIABLE" = "abcdef" ]
). Prawdopodobnie skrypty powinny zaczynać się tak prosto i przenośnie, jak to możliwe, dopóki nie będą naprawdę potrzebować funkcji specyficznych dla bash (z tego czy innego powodu). Ale w każdym razie intencja powinna być jasna; „=” i „==” oraz „[[” i „[” działają inaczej, a ich użycie powinno być spójne.[ "$var" = ".."]
zamiast==
, podczas gdy w C przypisuje zamiast testowania (i jest dość częstą przyczyną błędów) ... dlaczego nie „ttest
używać==
zamiast=
? ktokolwiek wie?/usr/bin/[
nie jest dowiązaniem symbolicznym do/usr/bin/test
, a nawet więcej: te programy mają nawet kilka różnych rozmiarów!)
jest częściącase
składni instrukcji kończącej wiersz wielkości liter. Nie ma nawiasu otwierającego. To mnie odrzuciło, gdy zobaczyłem to po raz pierwszy.Wsporniki
[1] http://wiki.bash-hackers.org/scripting/obsolete
Nawiasy klamrowe
Zdanie wtrącone
Podwójne nawiasy
źródło
$(varname)
nie ma związku ze składnią bash. Jest to część składni Makefile .$(varname)
nie ma związku ze składnią bash w twoim przypadku.Chciałem tylko dodać te z TLDP :
źródło
echo ${#ARRAY}
wyświetla trzy, ponieważ pierwszy elementARRAY
zawiera trzy znaki, a nie dlatego, że zawiera trzy elementy! Aby wydrukować liczbę elementów, użyjecho ${#ARRAY[@]}
.${TEST:-test}
jest równe,$TEST
jeśli zmiennaTEST
istnieje, w przeciwnym razie po prostu zwraca ciąg „test”. Jest jeszcze inna wersja, która robi jeszcze więcej:${TEST:=test}
--- która równa się również,$TEST
jeśli TEST istnieje, ale ilekroć nie istnieje, tworzy zmiennąTEST
i przypisuje wartość „test”, a także staje się wartością całego wyrażenia.Różnica między testem , [ i [[ jest szczegółowo wyjaśniona w BashFAQ .
I wniosek:
źródło
Nawiasy w definicji funkcji
()
W definicji funkcji używane są nawiasy :Oto powód, dla którego musisz uciec od nawiasów nawet w parametrach polecenia:
źródło
unset -f echo
. Zobaczyćhelp unset
.źródło