for i in $(xrandr); do echo "$i" ; done
for i in "$(xrandr)"; do echo "$i"; done
for i in "$(xrandr)"; do echo $i; done
Rozumiem, dlaczego 1 różni się od 2. Ale dlaczego 3 daje inny wynik niż 2? Proszę wyjaśnić również wynik. Jak cytaty działają na nowych liniach?
Odpowiedzi:
Niecytowana zmienna (jak w
$var
) lub podstawienie polecenia (jak w$(cmd)
lub`cmd`
) to operator split + glob w powłokach podobnych do Bourne'a.Oznacza to, że ich zawartość jest podzielona zgodnie z bieżącą wartością
$IFS
zmiennej specjalnej (która domyślnie zawiera znaki spacji, tabulacji i nowego wiersza)A następnie każde słowo powstałe w wyniku tego podziału podlega generowaniu nazw plików (zwanych także globowaniem lub rozszerzaniem nazw plików ), to znaczy są one uważane za wzorce i są rozwijane do listy plików pasujących do tego wzorca.
W związku z
for i in $(xrandr)
tym$(xrandr)
, ponieważ nie ma go w cudzysłowie, jest podzielony na ciągi znaków spacji, tabulacji i nowego wiersza. Każde słowo powstałe w wyniku tego podziału jest sprawdzane pod kątem pasujących nazw plików (lub pozostawione tak, jakby nie pasowały do żadnego pliku) ifor
zapętla je wszystkie.W
for i in "$(xrandr)"
nie używamy operatora split + glob, ponieważ cytowane jest podstawienie polecenia , więc w pętli jest jedno przejście na jedną wartość: wynikxrandr
(bez końcowych znaków nowego wiersza, które pasują do zastępowania poleceń ).Jednak w
echo $i
,$i
nie jest ponownie cytowany, więc ponownie treść$i
jest podzielona i podlega generowaniu nazw plików, a te są przekazywane jako osobne argumenty doecho
polecenia (iecho
wyprowadzają jego argumenty oddzielone spacjami).Lekcja nauczyła się:
$IFS
odpowiednio je ustaw i / lub włącz lub wyłącz generowanie nazw plików w razie potrzeby (set -f
,set +f
).Zazwyczaj w powyższym przykładzie, jeśli chcesz zapętlić pustą, oddzieloną listę słów na wyjściu
xrandr
, musisz:$IFS
wartość domyślną (lub usuń ją), aby podzielić na pusteset -f
do wyłączenia generowania nazw plików, chyba że jesteś pewien, żexrandr
nigdy nie wyprowadza dowolny*
lub?
lub[
znaków (które są symbole wieloznaczne stosowane we wzorcach generacji filename)A następnie używaj tylko operatora split + glob (pozostaw tylko zastępowanie poleceń lub rozwijanie zmiennych bez cudzysłowu) w
in
częścifor
pętli:Jeśli chcesz zapętlić (niepuste) linie danych
xrandr
wyjściowych, musisz ustawić$IFS
znak nowej linii:źródło
Cytowana nowa linia to nowa linia.
echo "$1"
Daje więc echo pojedynczego argumentu wiersza poleceń, który następnie drukuje nowe wiersze bezpośrednio.Niecytowana nowa linia to biała spacja.
echo $1
Daje więc echo wielu argumentów wiersza poleceń, które wypisują je jeden po drugim oddzielone spacjami.źródło