IFS null - это не то же самое, что не установленное IFS?


13

Здесь я прочитал большой вопрос под названием « Понимание IFS» . Я был удивлен, потому что ответы и комментарии цитируют POSIX, в котором говорится, что IFS = - это не то же самое, что отключение IFS. Если вы сбросили IFS, очевидно, используется значение по умолчанию. Если вместо этого сделать IFS пустым, разделителя нет. Я знал, что видел другой взгляд на это, и я нашел это в своих закладках:

Программирование Bourne Shell

$ IFS

Самое первое утверждение в вашем скрипте должно быть

IFS =

который сбрасывает разделитель поля ввода к его значению по умолчанию. В противном случае вы наследуете $ IFS от пользователя, который, возможно, установил для него какое-то странное значение, чтобы sh-строки анализировались иначе, чем вы ожидаете, и вызывали странное поведение.

Так было ли это правда некоторое время назад, или автор просто неправ?

Ответы:


20

Ответы, которые вы нашли на Stack Exchange, верны, а этот урок неверен. Вы можете экспериментировать самостоятельно или посмотреть его в стандарте . Unset IFSэквивалентно установке его в значение по умолчанию space-tab-newline, в то время как пустое IFSэффективно отключает разделение полей.

Вы можете обратиться к странице Свена Машека на IFS об исторических реализациях. Несколько исторических оболочек не понравились unset IFS, и очень старая версия ksh рассматривала его как пустую, IFSно все современные оболочки и большинство старых оболочек обрабатывают неустановленные значения IFSкак значения по умолчанию.

Вы не должны начинать свой сценарий, IFS=если только вы не хотите отключить разделение полей (что может быть разумным решением - но учтите, что вам все равно нужно заключать в кавычки двойные кавычки, чтобы избежать сбоев, если только вы не отключите это set -fтоже). Чтобы сбросить значение по умолчанию, используйте unset IFS. Это спорный вопрос, является ли полезным в начале сценария; Есть много других плохих вещей, таких как хитрость, PATHкоторую вызывающий может сделать, чтобы ваш сценарий пошёл не так.

Этот учебник также советует сбросить PATH. Обычно это плохой совет. В большинстве случаев вы не можете предсказать, каков правильный путь поиска, но пользователь знает. Как вы знаете , является ли /usr/local/binили /home/bob/binсодержат ошибки фиксированной версии утилита на древней UNIX , где те в /usr/binглючат? Вы действительно хотите внедрить всю логику, чтобы понять, стоит ли ее /usr/xpg6/binопередить /bin? На какой позиции вы хотите /usr/gnu/bin? Не сбрасывайте PATH, если ваш скрипт не нацелен на конкретную систему.

Я не читал этот урок, но проверил одну вещь: он не говорит вам с самого начала всегда ставить двойные кавычки вокруг подстановок переменных и подстановок команд. Поэтому я не считаю этот учебник хорошим.


unset IFSне сбрасывает IFS к его значению по умолчанию в bash, хотя он сбрасывает разделение полей.
Мелаб

@Melab unset IFSне сбрасывается IFSдо значения по умолчанию, он сбрасывает его. Но unset IFSимеет тот же эффект, что IFSи значение по умолчанию.
Жиль "ТАК - перестань быть злым"
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.