Na początku skryptu powłoki bash znajduje się następujący wiersz:
IFS=$'\n'
Jakie znaczenie ma ta kolekcja symboli?
bash
shell-script
command-line
Abdul Al Hazred
źródło
źródło
IFS=$'\n'
to bashism (+ inne powłoki, użyj ANSI-C Quoting , aby zapoznać się z obejściami zobacz stackoverflow.com/questions/10748703/…Odpowiedzi:
IFS
oznacza „wewnętrzny separator pól”. Jest on używany przez powłokę do określania sposobu dzielenia słów, tj. Rozpoznawania granic słów.Wypróbuj to w powłoce, takiej jak bash (inne powłoki mogą obsługiwać to inaczej, na przykład zsh):
Wartość domyślna dla
IFS
składa się ze spacji (a dokładniej: spacji, tabulacji i nowego wiersza). Każdy znak może być granicą wyrazu. Zatem przy domyślnej wartościIFS
powyższa pętla wyświetli:Innymi słowy, powłoka uważa, że białe znaki to granica słów.
Teraz spróbuj ustawić
IFS=:
przed wykonaniem pętli. Tym razem wynik jest następujący:Teraz skorupa dzieli się również
mystring
na słowa - ale teraz traktuje tylko dwukropek jako granicę słów.Pierwszy znak
IFS
jest specjalny: służy do rozgraniczenia słów na wyjściu, gdy używana jest$*
zmienna specjalna (przykład wzięty z Advanced Bash Scripting Guide , gdzie można również znaleźć więcej informacji na temat zmiennych specjalnych takich jak ta):Porównać do:
Należy zauważyć, że w obu przykładach, powłoka będzie nadal traktować wszystkich bohaterów
:
,-
a;
jak granice tekstu. Jedyne, co się zmienia, to zachowanie$*
.Inną ważną rzeczą, o której należy wiedzieć, jest sposób traktowania tak zwanych „białych znaków IFS” . Zasadniczo, gdy tylko
IFS
znaki białych znaków zostaną wstawione, początkowe i końcowe białe znaki są usuwane z ciągu znaków do podziału przed przetworzeniem, a sekwencja kolejnych znaków białych również ogranicza pola. Dotyczy to jednak tylko tych białych znaków, które są w rzeczywistości obecneIFS
.Na przykład spójrzmy na ciąg znaków
"a:b:: c d "
(spacja końcowa i dwa znaki spacji międzyc
id
).IFS=:
byłoby podzielić na cztery pola:"a"
,"b"
,""
(pusty ciąg znaków) i" c d "
(ponownie, dwie przestrzenie pomiędzyc
ad
). Zwróć uwagę na wiodące i końcowe białe znaki w ostatnim polu.IFS=' :'
, że będzie podzielony na pięć obszarów:"a"
,"b"
,""
(pusty ciąg znaków),"c"
a"d"
. Nigdzie nie ma wiodących i końcowych białych znaków.Zwróć uwagę, w jaki sposób wiele kolejnych białych znaków ogranicza dwa pola w drugim przykładzie, podczas gdy wiele kolejnych dwukropków nie (ponieważ nie są to białe znaki).
Jeśli chodzi o
IFS=$'\n'
, to jestksh93
składnia również obsługiwane przezbash
,zsh
,mksh
i FreeBSDsh
(z różnic między wszystkich powłok). Cytując stronę podręcznika bash:\n
jest sekwencją zmiany znaczenia dla nowej linii, więcIFS
kończy się na pojedynczym znaku nowej linii.źródło
bash
przewodnik skryptowy lub cokolwiek innego. Zasadniczo w informacjach dostępnych w takich linkach brakuje ważnych informacji. W każdym razie pomija dwa kluczowe punkty dotyczące podziału powłoki - globbing i IFS białe znaki.unset IFS
sprawia, że powłoka zachowuje się zupełnie inaczej niżIFS=
. Również pierwszy bajt w IFS jest wyjątkowy"${named_array[*]}"
- ale nie ma to znaczenia, gdy rozszerzenie nie jest$IFS
jest jedną z dwóch głównych rzeczy wykonywanych po rozwinięciu niecytowanej zmiennej w kontekście listy (jest tosplit
częśćsplit+glob
operatora). Drugi to globbing. Podczas korzystania z podziału pracy zwykle musisz wydaćset -f
polecenie wyłączeniaglob
części.$IFS
jest także używany przezread
wbudowane polecenieWewnątrz pojedynczych cudzysłowów niektóre znaki są specjalnie oceniane. Na przykład
\n
jest przetłumaczony do nowej linii.Tak więc ten konkretny wiersz przypisuje nowy wiersz do zmiennej IFS. Z kolei IFS jest specjalną zmienną w bash: Separator pól wewnętrznych. Jak
man bash
mówi toźródło
dollared single quotes
która różni się od prostych pojedynczych cytatów.Krótko mówiąc,
IFS=$'\n'
przypisz nowy wiersz\n
do zmiennejIFS
.$'string'
konstrukcja jest mechanizmem cytowania, który służy do dekodowania sekwencji ucieczkowych podobnych do ANSI C. Składnia ta pochodziksh93
, i był przenośny nowoczesnej powłoce jakbash
,zsh
,pdksh
,busybox sh
.Ta składnia nie jest zdefiniowana przez POSIX, ale została zaakceptowana dla wydania SUS 7 .
źródło
Wolałem wyjaśnić
$IFS
za pomocą przykładu:suppsoe chcesz cp lub mv lub inny proces przetwarzania plików, IFS jest pusty przez defualt, gdy twoje pliki mają meta char lub spację, takie jak:
Linux Administration.pdf
lubFree Software Fundation.ogg
, na pewno będziesz mieć problem, ponieważ: Linux rozważa oddzielny parametr i Administracja uważają oddzielny parametr. Więc bash mabuilt-in variable
, Następnie możesz zainicjowaćIFS==$(echo -en "\n\b")
, Następnie bash odrzuci dowolny meta char i spację między nazwą pliku, na przykład:źródło