Jeśli poniższy przykład, który ustawia IFS
zmienną środowiskową na znak wysuwu wiersza ...
IFS=$'\n'
- Co dokładnie oznacza znak dolara ?
- Co robi w tym konkretnym przypadku?
- Gdzie mogę przeczytać więcej na temat tego konkretnego zastosowania (Google nie zezwala na znaki specjalne w wyszukiwaniu i nie wiem, czego szukać w innym przypadku)?
Wiem, co to IFS
jest zmienna środowiskowa i jaki jest jej \n
znak ( nowy wiersz), ale dlaczego nie użyć następującego formularza:
IFS="\n"
(który nie działa)?
Na przykład, jeśli chcę zapętlić każdy wiersz pliku i chcę użyć pętli for, mogę to zrobić:
for line in (< /path/to/file); do
echo "Line: $line"
done
Jednak to nie zadziała poprawnie, chyba że IFS
zostanie ustawione na znak wysuwu wiersza. Aby to zadziałało, musiałbym to zrobić:
OLDIFS=$IFS
IFS=$'\n'
for line in (< /path/to/file); do
echo "Line: $line"
done
IFS=$OLDIFS
Uwaga: nie potrzebuję innego sposobu na zrobienie tego samego, znam już wiele innych ... Ciekawi mnie tylko to $'\n'
i zastanawiałem się, czy ktoś mógłby mi to wyjaśnić.
\n
to po prostu (uciekana) litera n. Masz rację'\n'
i"\n"
masz odwagę, po której następuje n.$'\n'
jest to specyficzne dla basha - nie będzie działać w powłoce POSIX (/bin/sh
). Aby uzyskać ten sam efekt w sposób zgodny z POSIX, możesz wpisaćIFS='
, a następnie nacisnąć klawisz Return, aby wpisać rzeczywisty znak nowej linii, a następnie wpisać zamknięcie'
IFS=$(echo -e '\n')
powinien również zrobić to w sposób zgodny z POSIX.-e
nie jest zdefiniowane i\n
bez-e
działa jako rozszerzenie XSI: pubs.opengroup.org/onlinepubs/9699919799/utilities/… .printf '\n'
skały;)Wystarczy dać konstrukt swoją oficjalną nazwę : ciągi postaci
$'...'
nazywane są ANSI C cudzysłowów .Oznacza to, że podobnie jak w łańcuchach [ANSI] C, sekwencje specjalne z odwrotnym ukośnikiem są rozpoznawane i rozszerzane do ich dosłownego odpowiednika (pełna lista obsługiwanych sekwencji specjalnych znajduje się poniżej).
Po tym rozwinięciu
$'...'
łańcuchy zachowują się tak samo jak'...'
łańcuchy - tj. Są traktowane jako literały NIE podlegające żadnym [dalszym] rozszerzeniom powłoki .Na przykład,
$'\n'
interpretuje się do dosłownego znaku nowej linii - czego nie może zrobić zwykły literał ciągu basha (czy'...'
lub"..."
). [1]Inną interesującą cechą jest to, że ciągi znaków ANSI w cudzysłowach C mogą uciec
'
(pojedyncze cudzysłowy)\'
, ponieważ'...'
(zwykłe ciągi w apostrofach) nie mogą:Lista obsługiwanych sekwencji ucieczki :
[1] Możesz jednak osadzić rzeczywiste znaki nowej linii w łańcuchach „…” i „…”; tj. można zdefiniować ciągi obejmujące wiele linii.
źródło
Z http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html :
Wydaje mi się, że wymusza to na skrypcie ucieczkę z wysuwu wiersza do odpowiedniego standardu ANSI-C.
źródło
Odzyskiwanie domyślnego IFS
OLDIFS=$IFS
- nie jest to konieczne. Uruchom nowy IFS w podpowłoce, aby uniknąć zastąpienia domyślnego IFS:Poza tym nie wierzę, że w pełni odzyskasz stary IFS. Powinieneś cytować go podwójnie, aby uniknąć łamania wiersza, takiego jak
OLDIFS="$IFS"
.źródło
args=$(IFS='&'; echo "$*")
. przywrócenieIFS
go$' \t\n'
w sposób przyjazny dla powłoki Bourne'a to nie lada wyczyn.Besides I don't really believe you recover the old IFS fully
: podział na słowa jest nie wykonywane na RHS przypisania zmiennych (ale usuwanie cytat), takOLDIFS=$IFS
iOLDIFS="$IFS"
zachowują się tak samo.Ciągi w cudzysłowie ANSI C są kluczowym punktem. Dzięki @ mklement0.
Możesz przetestować ciągi znaków ANSI w cudzysłowie C za pomocą polecenia od.
Wyjścia:
Możesz jasno poznać znaczenie dzięki wynikom.
źródło
To jak pobieranie wartości ze zmiennej:
są różne, więc znak dolara zasadniczo ocenia zawartość.
źródło
$'FOO'
(w przeciwieństwie do$FOO
tego, o co nie chodziło w tym pytaniu) jest ciągiem znaków. Jeśli wykonaszecho $'VAR'
, zobaczysz, że drukuje łańcuchVAR
, a nietest
.