розуміння значення за замовчуванням IFS


10

У моїй GNU bash версії 4.2.8 IFS має значення за замовчуванням простір, вкладку та канал рядків за замовчуванням:

usr@T42 ~ $ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|
00000003
usr@T42 ~ $ 

Чи є причина таких стандартних IFS? Крім того, які утиліти використовують IFS, крім вбудованого bash read?

Відповіді:


13

Змінна IFS використовується щоразу, коли оболонка виконує завдання під назвою розділення слів . Найпоширеніші випадки, коли це використовується, - це після розширення параметрів (наприклад $var) або заміни команди (наприклад, $(some-command)або застарілих посилань) в команді. Тут, якщо розширення містить будь-які IFSсимволи, воно розбивається на різні 'слова' перед тим, як команда буде оброблена. Фактично це означає, що ці символи розділяють замінений текст на різні аргументи (включаючи ім'я команди, якщо змінна вказана спочатку).

Таким чином, причиною значення IFSпробілу, вкладки та нового рядка за замовчуванням є те, що це символи пробілу, від яких зазвичай слід розбити слово.

Один із способів запобігти поділу слова - це використовувати подвійні лапки навколо розширення ( "$var") - адже ви це зробили у своєму запитанні. Якби ви цього не зробили, не було б результату, echoоскільки не було б аргументів, а лише розділення аргументів символів.

Зауважте також, що два місця, де розділення слів не відбувається після розширення параметрів, мають присвоєння змінної (наприклад, var=$othervarі var=$(somecommand)це нормально), а також в межах [[ ]]конструкції ( [[ $var = $othervar ]]це нормально, але [ $var = $othervar ]слід цитувати).

Нарешті, як колись на мене вказав мудрець, поширене неправильне уявлення про те, що запобігання розщепленню слів є єдиною причиною цитувати змінну. Це не так, цитування також запобігає розширенню імені шляху або розширенню глобального типу, як це більше відомо. Якщо змінна містить такі символи як глобальні, *то вони можуть бути розширені в імена файлів, коли змінна використовується без котирування в команді. Наприклад, врахуйте:

var=*
echo $var

Це відобразить імена файлів у поточному каталозі.

Як вказує Стефан нижче , порядок знаків всередині IFSє значним при розширенні "$*". На bashчоловіковій сторінці:

"$*" is equivalent to "$1c$2c...", where c is the first character of the value of
the IFS variable.  If IFS is unset, the parameters are separated by spaces.  If
IFS is null, the parameters are joined without intervening separators.

Щоб отримати більше прикладів розділення слів, див. Цю відповідь - https://unix.stackexchange.com/a/118444/48083


1
Перший символ $IFSтакож використовується в "$*"тому, чому питання має значення.
Стефан Шазелас

2
Також зауважте, що zshза замовчуванням входить символ NUL $IFS(інші оболонки не підтримують утримування символу NUL у своїх змінних).
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.