Skrypt bash, który zawiera
for i in {a,b}-{1,2}; do
echo $i;
done
odciski
a-1
a-2
b-1
b-2
po wykonaniu. Tego się spodziewałem - w miarę {a,b}
rozszerzania konstrukcji.
Jednak gdy (inny) skrypt zawiera
v={a,b}-{1,2}
echo $v
drukuje
{a,b}-{1,2}
czego się nie spodziewałem. Spodziewałem się, że to wydrukuje a-1 a-2 b-1 b-2
. Oczywiście {a,b}
konstrukcja nie jest rozwinięta.
Mogę tak rozwinąć
v=$(echo {a,b}-{1,2})
Na podstawie tych obserwacji mam dwa pytania: 1) kiedy {a,b}
rozwinięto konstrukcję? 2) Czy $(echo {a,b}-{1,2})
preferowany sposób uruchomienia rozszerzenia jest wymagany?
bash
brace-expansion
René Nyffenegger
źródło
źródło
=
. Na przykładv=a-1 a-2
nie będzie działać.v=a-1 a-2
oznaczaassign 'a-1' to variable v and run 'a-2'
v=(a-1 a-2)
przypisuje tablicę do zmiennejv
.v+=(b-1 b-2)
dołącza się do tego.Odpowiedzi:
Podręcznik Bash mówi, że:
Rozszerzenie nawiasu klamrowego nie znajduje się na liście, więc nie jest wykonywane dla przypisania
v={a,b}-{1,2}
. Jak wspomniano w @Wildcard, proste rozszerzenie do i takv=a-1 v=b-1 ...
byłoby bez sensu.Ponadto podczas wykonywania
echo $v
obowiązują następujące zasady:Rozwinięcie nawiasów następuje przed rozwinięciem zmiennej, więc przypisane nawiasy klamrowe
$v
nie są rozwijane.Ale możesz robić takie rzeczy:
Rozwinięcie go za pomocą
$(echo ...)
powinno działać, jeśli nie ma żadnych białych znaków w ciągu, który ma zostać rozwinięty, a zatem nie będzie miał problemów z dzieleniem słów. Lepszym sposobem może być użycie zmiennej tablicowej, jeśli możesz.np. zapisz rozwinięcie do tablicy i uruchom polecenie z rozszerzonymi wartościami:
źródło
Ciekawy punkt. Prawdopodobnie pomocny jest następujący fragment
man bash
:Zauważ, że rozwinięcie nawiasu NIE jest wymienione na liście.
Pozostaje jednak pytanie, a mianowicie: Skąd powłoka wie, że jest to zmienne przypisanie, a zatem nie podlega rozszerzaniu nawiasów? A dokładniej, gdzie sekwencja analizowania jest wyjaśniona i skodyfikowana tak, że powłoka jest zdefiniowana w celu identyfikacji przypisań zmiennych, zanim zajmie się rozszerzaniem nawiasów? (Tak oczywiście
bash
działa, ale nie znalazłem dokładnej linii dokumentacji opisującej to.)źródło
LESS=+/SIMPLE man bash
).zgodnie z moją wiedzą, {a, b, c} jest rozszerzane, gdy jest bezpośrednio odbijane echem lub używane z poleceniem np .: mkdir ~ / {a, b, c}, ale kiedy jest ustawione na zmienną, powinno zostać ocenione przed odbijanie go lub używanie go jako argumentu!
ponieważ masz „a”, po którym następuje „b” w kolejności alfa [az], i „1”, a następnie „2” w kolejności decyzyjnej [0–9]: możesz użyć podwójnej kropki „..” insteed przecinku, „
źródło
v
nie ustawiono na literalny ciąg „a-1 a-2 b-1 b-2”. A przynajmniej dlaczego nie pojawił się żaden błąd, gdy sięv=a-1 v=a-2 v=b-1 v=b-2
pojawi, jeśli wpiszesz polecenie: (do którego można by się rozszerzyć przypisania zmiennej). To dobre pytanie; to tak naprawdę nie odpowiada.Przypisanie zmiennej do bash nie rozwija wyrażenia.
Dla tego małego skryptu x będzie zawierać,
"*"
a nie rozszerzenie"*"
:Jednak niektóre wartości są rozszerzone, zob. ładna odpowiedź od ilkkachu.
Wyrażenia są rozszerzane podczas ich oceny.
Lubię to:
Lub tak:
Lub tak:
Wyzwalanie
$()
jest dość powszechne i myślę, że jest preferowane w stosunku doeval
, ale najlepsze jest prawdopodobnie wcale nie wyzwalanie oceny, dopóki zmienna nie zostanie faktycznie użyta w poleceniu.źródło