В начале сценария оболочки bash находится следующая строка:
IFS=$'\n'
В чем смысл этой коллекции символов?
bash
shell-script
command-line
Абдул Аль Хазред
источник
источник
IFS=$'\n'
является bashism (+ другие оболочки, использовать ANSI-C Цитирование , для обхода см stackoverflow.com/questions/10748703/...Ответы:
IFS
расшифровывается как «внутренний разделитель полей». Он используется оболочкой для определения того, как выполнять разбиение слов, то есть как распознавать границы слов.Попробуйте это в оболочке, такой как bash (другие оболочки могут обрабатывать это по-разному, например, zsh):
Значение по умолчанию для
IFS
состоит из пробельных символов (если быть точным: пробел, табуляция и новая строка). Каждый символ может быть границей слова. Таким образом, со значением по умолчаниюIFS
, цикл выше напечатает:Другими словами, оболочка считает, что пробел является границей слова.
Теперь попробуйте установить
IFS=:
перед выполнением цикла. На этот раз результат:Теперь оболочка также разбивается
mystring
на слова - но теперь она рассматривает только двоеточие как границу слова.Первый символ
IFS
- специальный: он используется для разделения слов в выводе при использовании специальной$*
переменной (пример взят из Руководства по расширенному написанию сценариев Bash , где вы также можете найти дополнительную информацию о специальных переменных, подобных этой):По сравнению с:
Обратите внимание , что в обоих примерах, оболочка будет по- прежнему относиться все символы
:
,-
а;
также границы слов. Единственное, что меняется, это поведение$*
.Еще одна важная вещь, которую нужно знать, это то, как обрабатываются так называемые «пробелы IFS» . По сути, как только
IFS
включаются пробельные символы, начальные и конечные пробельные символы удаляются из строки, которая должна быть разделена перед обработкой, а также последовательность последовательных пробельных символов также разделяет поля. Однако это относится только к тем пробельным символам, которые фактически присутствуют вIFS
.Например, давайте посмотрим на строку
"a:b:: c d "
(завершающий пробел и два пробела между символамиc
иd
).IFS=:
он будет разделен на четыре поля:"a"
,"b"
,""
(пустая строка) и" c d "
(опять же , два пространства междуc
иd
). Обратите внимание на начальные и конечные пробелы в последнем поле.IFS=' :'
, она будет разделена на пять полей:"a"
,"b"
,""
(пустая строка),"c"
и"d"
. Нет ни одного начального и конечного пробела.Обратите внимание, что во втором примере несколько последовательных пробельных символов разделяют два поля, а несколько последовательных двоеточий - нет (поскольку они не являются пробельными символами).
Что же касается
IFS=$'\n'
, то естьksh93
синтаксис также поддерживаетсяbash
,zsh
,mksh
и FreeBSDsh
(с вариациями между всеми оболочками). Цитирую man-страницу bash:\n
является escape-последовательностью для новой строки, поэтому вIFS
конечном итоге устанавливается один символ новой строки.источник
bash
руководство по написанию сценариев или что-то еще. В основном, информация, доступная по таким ссылкам, не хватает важными способами. Во всяком случае, таким образом, упускается два важных момента, касающихся расщепления оболочки - глобализация и пропуски IFS.unset IFS
оболочка ведет себя совсем иначе, чемIFS=
. Кроме того, первый байт в IFS также особенный,"${named_array[*]}"
но не имеет значения, когда расширение не$IFS
- одна из двух основных вещей, выполняемых при раскрытии переменной без кавычек в контексте списка (этоsplit
частьsplit+glob
оператора). Другой болтается. При использовании разделения работы, как правило, необходимоset -f
отключить этуglob
часть.$IFS
также используетсяread
встроенной командойВнутри долларовых одинарных кавычек некоторые символы оцениваются специально. Например,
\n
переводится на новую строку.Таким образом, эта конкретная строка присваивает новую строку переменной IFS. IFS, в свою очередь, является специальной переменной в bash: Разделитель внутренних полей. Как
man bash
говорится, этоисточник
dollared single quotes
которое отличается от простых одинарных кавычек.Для краткости,
IFS=$'\n'
присвойте новую строку\n
переменнойIFS
.$'string'
Конструкция - это механизм цитирования, который используется для декодирования ANSI C, как escape-последовательности. Этот синтаксис исходит отksh93
, и был портативным современной оболочке , какbash
,zsh
,pdksh
,busybox sh
.Этот синтаксис не определен POSIX, но был принят для выпуска SUS 7 .
источник
Я предпочел объяснить
$IFS
на примере:если вы хотите, чтобы cp, mv или другой файл обрабатывались, IFS пуст по умолчанию, когда ваши файлы имеют метасимвол или пробел, например:
Linux Administration.pdf
илиFree Software Fundation.ogg
, конечно, у вас будет проблема, потому что: Linux рассматривает отдельный параметр и Администрация рассматривают отдельный параметр. Итак, bash имеетbuilt-in variable
, затем вы можете инициализироватьIFS==$(echo -en "\n\b")
, затем bash отбрасывает любой метасимвол и пробел между именем файла, например:источник