Формат INI используется для хранения настроек приложений с ранних дней Windows и остаётся активно используемым в Python-проектах, конфигурациях PHP, MySQL, Git и десятках других инструментов. Создать его правильно требует понимания нескольких правил синтаксиса, знания того, где парсеры расходятся в поведении, и выбора правильного формата для вашего сценария. Это руководство охватывает всё — от первой строки до валидации.
Что такое INI-файл?
INI-файл — это текстовый конфигурационный файл, хранящий настройки в виде пар «ключ-значение», опционально сгруппированных в именованные секции. Название происходит от «initialisation» (инициализация) — INI-файлы использовались для инициализации Windows-приложений с их настройками до появления реестра Windows. Формат никогда не имел формальной спецификации, но де-факто стандарт сложился благодаря широкому использованию.
Где INI-файлы используются сегодня
- Упаковка Python — `setup.cfg`, `tox.ini`, `pytest.ini`, `mypy.ini`, `.flake8`
- Среда выполнения PHP — `php.ini` глобально управляет настройками интерпретатора PHP
- MySQL / MariaDB — `my.ini` (Windows) и `my.cnf` (Unix) настраивают сервер базы данных
- Git — `.gitconfig` и `.git/config` используют формат, подобный INI, для настроек репозитория и пользователя
- Wine — `wine.inf` настраивает слой совместимости Windows на Linux и macOS
- Windows-приложения — тысячи старых и современных десктопных программ хранят настройки в `.ini`-файлах в папке AppData
INI и реестр Windows
Microsoft перенесла настройки Windows-приложений в реестр в начале 1990-х ради производительности и централизованного управления. Однако многие разработчики по-прежнему предпочитают INI-файлы за переносимость — INI-файл можно просмотреть и отредактировать любым текстовым редактором, закоммитить в систему контроля версий и скопировать между машинами без каких-либо средств экспорта/импорта. Реестр этого не умеет.
Note
Правила синтаксиса INI-файлов
Несмотря на отсутствие формальной спецификации, синтаксис INI следует единообразным конвенциям практически во всех парсерах. Это правила, на которые можно полагаться независимо от того, что читает ваш файл.
INI-файл — простейший из возможных конфигурационных форматов: секции в квадратных скобках, пары ключ-значение под ними и точки с запятой для комментариев. Всё остальное — специфика конкретного парсера.
Универсальные правила
- Одна пара ключ-значение на строку — `key = value` или `key=value`; пробелы вокруг `=` необязательны, но единообразные пробелы читабельнее
- Заголовки секций — `[ИмяСекции]` на отдельной строке; без содержимого после закрывающей скобки
- Строки комментариев — начинайте с `;` для максимальной совместимости; `#` поддерживается некоторыми парсерами (`configparser` Python, инструменты Linux), но не нативными API Windows
- Пустые строки — игнорируются всеми парсерами; свободно используйте их для разделения логических групп внутри секции
- Без вложенности — INI плоский: секции содержат пары ключ-значение, а не другие секции
- Строковые значения — все значения являются строками, если парсер их не конвертирует; `count = 5` для большинства парсеров — строка «5»
Что видит парсер
Парсер строит двухуровневую карту: имя секции → ключ → значение. Если в файле нет заголовков секций, значения находятся в неявной «дефолтной» секции — `configparser` Python называет её `DEFAULT`. Сливает ли парсер дефолтную секцию с именованными — зависит от реализации. Ключи и имена секций почти повсеместно считаются регистронезависимыми по конвенции, хотя это не гарантируется всеми реализациями.
Tip
Создание первого INI-файла
Создать INI-файл можно менее чем за пять шагов. Единственный необходимый инструмент — простой текстовый редактор; подойдёт любой редактор, сохраняющий в UTF-8 или ASCII без метки порядка байтов (BOM).
Создайте новый текстовый файл с расширением .ini
Откройте текстовый редактор (VS Code, Блокнот, nano, vim — подойдёт любой) и создайте новый файл. Сохраните его с расширением `.ini` до написания содержимого, чтобы редактор при наличии применил подсветку синтаксиса INI. В Windows убедитесь, что в Блокноте в поле «Тип файла» выбрано «Все файлы», чтобы файл не сохранился как `config.ini.txt` вместо `config.ini`.
Добавьте первый заголовок секции
Напишите первое имя секции в квадратных скобках на отдельной строке. Имена секций — описательные метки; `[database]`, `[server]`, `[logging]` — общепринятые варианты. Также можно сразу писать пары ключ-значение без какого-либо заголовка секции, если конфигурация достаточно проста и не требует группировки.
Добавьте пары ключ-значение под каждой секцией
Под заголовком секции пишите одну пару `key = value` на строку. Ключи должны быть строчными с подчёркиваниями (snake_case) для максимальной межпарсерной совместимости. Значения могут содержать пробелы, пунктуацию и большинство специальных символов. Не заключайте значения в кавычки — большинство парсеров считает кавычки обычными символами, а не строковыми ограничителями.
Добавьте комментарии для документирования неочевидных значений
Начинайте строки комментариев с точки с запятой (`;`). Комментарии должны находиться на отдельной выделенной строке — комментарий после значения на той же строке (`host = localhost ; primary DB`) не поддерживается надёжно всеми парсерами и может попасть в значение. Если нужны заметки в строке, поместите их на предыдущую строку отдельным комментарием.
Провалидируйте готовый файл
Вставьте ваш готовый INI-файл в INI-валидатор, чтобы проверить синтаксические ошибки, дублирующиеся имена секций и соответствие формату. Валидатор сообщает о проблемах с номерами строк, чтобы вы могли исправить их до вывода файла в продакшен. Если нужно единообразное форматирование, прогоните файл сначала через INI-форматтер.
INI-валидатор
Проверяйте любой INI- или CFG-файл на синтаксические ошибки, дубли секций и соответствие формату — отчёты об ошибках с точностью до строки без необходимости загрузки файлов.
Секции, ключи и значения подробно
Три структурных элемента INI-файла — секции, ключи и значения — имеют правила и краевые случаи, которые стоит понять до написания конфигурации, которую будет читать чужой парсер.
Конвенции именования секций
Имена секций заключаются в квадратные скобки и располагаются на отдельной строке. Они могут содержать буквы, цифры, пробелы и большинство знаков препинания — но пробелы в именах секций плохо поддерживаются некоторыми парсерами, их следует избегать. Используйте `[DatabaseConfig]` или `[database_config]`, а не `[database config]`. Дублирующиеся имена секций либо сливаются, либо вызывают ошибку в зависимости от парсера — считайте их запрещёнными и валидируйте через INI-валидатор, чтобы ловить дубликаты.
Правила именования ключей
Ключи не должны содержать знак `=` или перенос строки. Помимо этого, конвенции различаются, но самый безопасный подход — использовать только строчные буквы, цифры и подчёркивания — те же правила, что для имён переменных Python. Избегайте дефисов в ключах, если планируете читать их в Python через `configparser`, поскольку Python возвращает ключи как есть, а ключи с дефисом нельзя обращаться как атрибуты.
Типы значений и многострочные значения
Все значения в INI-файлах — строки, если ваш парсер явно их не конвертирует. `enabled = true` — это строка «true» — ваш код должен превратить её в булево значение. `configparser` Python предоставляет для этого методы `getboolean()`, `getint()` и `getfloat()`. Многострочные значения поддерживаются некоторыми парсерами (в `configparser` Python строки с ведущими пробелами считаются продолжением предыдущего значения), но не всеми — проверьте документацию вашего парсера, прежде чем полагаться на это.
Секция DEFAULT
`configparser` Python считает секцию с именем `[DEFAULT]` (регистронезависимо) специальной резервной секцией. Любой ключ, определённый в `[DEFAULT]`, доступен во всех остальных секциях как резерв — если секция не определяет ключ, вместо него возвращается значение из `[DEFAULT]`. Это поведение, специфичное для Python, которого нет в большинстве других парсеров. Если вы пишете INI-файлы специально для Python, `[DEFAULT]` — удобный способ определить общие значения без повторения в каждой секции.
Warning
Чтение INI-файлов в коде
Большинство языков предоставляют встроенный или библиотечный парсер для INI-файлов. Вот стандартные подходы для самых распространённых сред.
Python: configparser
Модуль `configparser` Python — стандартный способ читать INI-файлы в Python. Импортируйте его, создайте экземпляр `ConfigParser()`, вызовите `.read()` с именем файла и получайте доступ к значениям через `config["ИмяСекции"]["ключ"]` или `config.get("ИмяСекции", "ключ")`. Метод `.get()` принимает аргумент `fallback`, возвращающий значение по умолчанию, когда ключ отсутствует — полезно для необязательных конфигурационных значений. Используйте `getboolean()`, `getint()` и `getfloat()` для типизированных значений вместо ручного приведения строк.
PHP: parse_ini_file()
PHP предоставляет `parse_ini_file($filename, $process_sections)` как встроенную функцию. С `$process_sections = true` функция возвращает вложенный ассоциативный массив, организованный по именам секций. С `false` возвращает плоский массив со всеми слитыми ключами. Парсер PHP строг к определённым специальным символам в некавыченных значениях — значения, содержащие =, фигурные скобки, |, &, ~, !, [, ], нужно брать в кавычки в INI-файле, чтобы они корректно разбирались.
Node.js и другие среды
В Node.js нет встроенного INI-парсера, но npm-пакет `ini` (лицензия MIT) предоставляет стандартные интерфейсы `parse()` и `stringify()`. Для Java стандартный выбор — библиотека `org.ini4j`. Для Go наиболее используемый вариант — пакет `gopkg.in/ini.v1`. Во всех случаях библиотека обрабатывает ту же двухуровневую структуру секция/ключ — формы API различаются, но базовый формат идентичен.
Tip
INI vs TOML vs YAML
INI — не всегда правильный конфигурационный формат. Понимание того, где он уместен — и где TOML или YAML лучше — помогает принять верное решение для новых проектов.
| Характеристика | INI | TOML | YAML |
|---|---|---|---|
| Сложность синтаксиса | Минимальная | Умеренная | Высокая |
| Нативная поддержка типов | ✗ Только строки | ✓ Полные типы | ✓ Полные типы |
| Вложенные структуры | ✗ Максимум два уровня | ✓ Инлайн-таблицы | ✓ Неограниченная глубина |
| Массивы / списки | ✗ Нестандартно | ✓ Нативные массивы | ✓ Блочные последовательности |
| Комментарии | ✓ ; и # | ✓ Только # | ✓ Только # |
| Формальная спецификация | ✗ Нет официальной спецификации | ✓ Спецификация TOML | ✓ Спецификация YAML 1.2 |
| Лучше всего для | Простая конфигурация приложений | Rust, пакеты Python | DevOps, Kubernetes |
| Читаемость | Очень высокая | Высокая | Средняя (зависит от отступов) |
Когда использовать INI
INI — правильный выбор, когда конфигурация двухуровневая (секции и плоские пары ключ-значение), когда целевой парсер уже ожидает формат INI (PHP, экосистема Python, MySQL, Git) и когда нужен максимально простой формат, который любой разработчик прочитает без предварительных знаний. Он не подходит для конфигураций, требующих массивов, вложенных объектов или типизированных данных.
Когда использовать TOML или YAML вместо него
Выбирайте TOML, когда конфигурации нужны типизированные значения, массивы или инлайн-таблицы и нужна строгая спецификация с предсказуемым парсингом. TOML — формат для `pyproject.toml`, `Cargo.toml` и конфигурационных файлов Hugo. Выбирайте YAML, когда нужны глубоко вложенные структуры или вы работаете в экосистеме, где YAML уже стандарт — Kubernetes, GitHub Actions, Docker Compose и Ansible — все среды, ориентированные на YAML.
Key takeaways
- INI-файл — это текстовый конфигурационный файл с именованными секциями в `[квадратных скобках]` и парами `key = value` под ними.
- Используйте `;` для комментариев — не `#` — для максимальной совместимости между Windows, PHP, Python и другими INI-парсерами.
- Сохраняйте INI-файлы как UTF-8 без BOM; избегайте инлайн-комментариев (после значения на той же строке), так как они поддерживаются не везде.
- Все значения INI — строки, если парсер явно их не конвертирует — используйте `getboolean()`, `getint()` и `getfloat()` в Python.
- Никогда не храните пароли или API-ключи в INI-файлах, закоммиченных в систему контроля версий — для чувствительных значений используйте переменные окружения.
- Валидируйте через INI-валидатор перед развертыванием, чтобы поймать синтаксические ошибки, дубли секций и проблемы формата.
- Используйте TOML для конфигураций с типизированными значениями и массивами; YAML — для глубоко вложенных структур — INI идеален только для простых двухуровневых конфигураций.
Комментарии и кодировка
Комментарии и кодировка символов — два аспекта INI-файлов, чаще всего вызывающие незаметные проблемы при обмене файлами между разными инструментами, операционными системами и языками программирования.
Символы комментариев: ; против #
Точка с запятой (`;`) — универсально поддерживаемый символ комментария — работает в `configparser` Python, нативных API Windows, `parse_ini_file()` PHP, MySQL и практически в любом другом INI-парсере. Решётка (`#`) поддерживается `configparser` Python и большинством парсеров на базе Linux, но не поддерживается `GetPrivateProfileString()` Windows. Если ваш INI-файл будет читать только Python, безопасен любой символ. Для кроссплатформенных файлов используйте исключительно `;`.
Кодировка символов: UTF-8 против Windows-1252
Сохраняйте INI-файлы как UTF-8 без BOM для современных инструментов. BOM (метка порядка байтов, невидимый символ `\uFEFF` в начале некоторых UTF-8-файлов, сохранённых инструментами Windows) вызывает проблемы в парсерах, которые принимают его за часть первого имени ключа. `configparser` Python нативно обрабатывает UTF-8 начиная с Python 3. Если вы пишете INI-файл для устаревшего Windows-приложения, ожидающего кодировку Windows-1252, подстройтесь под ожидания приложения — смешение кодировок — частая причина порчи символов в значениях.
Концы строк
INI-файлы работают и с концами строк Windows (CRLF, `\r\n`), и с Unix (LF, `\n`). Используйте конвенцию целевой платформы. Если вы редактируете INI-файл в Windows для развертывания на Linux, настройте редактор сохранять с концами строк LF, чтобы символ возврата каретки не появился в значениях на Linux-парсерах. INI-форматтер нормализует концы строк и пробелы за один проход.