Переход на операционные системы семейства Linux ставит перед разработчиками 1С ряд специфических задач, с которыми мы редко сталкиваемся в среде Windows. Одна из таких задач — программное управление файловой структурой, в частности, создание каталогов для хранения кэша или временных данных. В этой статье мы подробно разберем, почему привычные методы могут выдавать ошибки доступа, как правильно работать с путями в Linux и как обеспечить корректную работу кода как на стороне клиента, так и на стороне сервера.
Рассмотрим ситуацию: разработчик пытается создать каталог, используя стандартный для Linux путь к домашней директории пользователя через символ тильды ~. При вызове метода СоздатьКаталог("~/.1cv8/1C/1cv8/my_cache") платформа возвращает ошибку: «Ошибка доступа к файлу '~'. 13(0x0000000D): Permission denied».
Выясним причину этой ошибки. В Linux символ ~ является «синтаксическим сахаром» командной оболочки (например, Bash). Когда вы вводите его в терминале, оболочка сама подставляет вместо него полный путь к домашнему каталогу текущего пользователя (например, /home/user). Однако метод 1С СоздатьКаталог() обращается напрямую к системным вызовам операционной системы. Ядро Linux не умеет интерпретировать тильду самостоятельно — оно воспринимает её как буквальное имя папки в текущем рабочем каталоге. Поскольку у пользователя обычно нет прав на создание папок с таким странным именем в корневых или системных директориях приложения, мы получаем ошибку доступа.
Проанализируем структуру папок 1С. В Windows пути /1Cv8/ и /1cv8/ идентичны, но в Linux это два совершенно разных каталога. Стандартная структура папок 1С в домашнем каталоге выглядит следующим образом:
.1cv8 (скрытая папка, начинается с точки);1C (заглавная С);1cv8 (строчная v).Важный момент: если вы ошибетесь в регистре хотя бы одного символа, метод либо создаст параллельную ветку каталогов, которую платформа не увидит, либо завершится ошибкой, если у пользователя недостаточно прав на создание новых папок в родительских директориях.
Самый надежный и правильный способ создания каталога в 1С — использование абсолютного пути. Чтобы узнать путь к домашней директории программно, воспользуемся переменными окружения. Проанализируем пример кода, который будет работать универсально:
// Получаем путь к домашнему каталогу пользователя
ДомашнийКаталог = ПолучитьПеременнуюОкружения("HOME");
Если ПустаяСтрока(ДомашнийКаталог) Тогда
// Если переменная HOME не определена, можно попробовать USERPROFILE (для кроссплатформенности)
ДомашнийКаталог = ПолучитьПеременнуюОкружения("USERPROFILE");
КонецЕсли;
Если Не ПустаяСтрока(ДомашнийКаталог) Тогда
// Формируем правильный путь с учетом регистра
ЦелевойПуть = ДомашнийКаталог + "/.1cv8/1C/1cv8/my_custom_cache/";
// Создаем каталог
Попытка
СоздатьКаталог(ЦелевойПуть);
Сообщить("Каталог успешно создан: " + ЦелевойПуть);
Исключение
Сообщить("Не удалось создать каталог: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Этот метод хорош тем, что он не зависит от настроек командной оболочки и использует штатные механизмы платформы 1С.
Если нам все же необходимо использовать возможности командной оболочки (включая тильду или автоматическое создание всей цепочки вложенных папок), мы можем воспользоваться методом КомандаСистемы(). В Linux для создания каталогов используется утилита mkdir. Флаг -p позволяет создать всю структуру вложенности (parent directories) за один раз и не выдает ошибку, если папка уже существует.
Рассмотрим пример реализации:
ПутьККаталогу = "~/.1cv8/1C/1cv8/new_folder";
// Используем mkdir с флагом -p для безопасного создания
Команда = "mkdir -p " + ПутьККаталогу;
КомандаСистемы(Команда);
Обратите внимание: КомандаСистемы() в Linux запускает процесс через оболочку, поэтому тильда ~ здесь будет успешно преобразована в путь к домашнему каталогу. Однако помните, что этот метод сложнее отлаживать, так как он не возвращает результат выполнения напрямую в 1С.
Разберем ситуацию, когда код выполняется на стороне сервера. Серверный процесс 1С в Linux обычно запускается под специальным техническим пользователем usr1cv8. Его домашний каталог по умолчанию — /home/usr1cv8/.
При работе на сервере переменная HOME также будет указывать на домашнюю директорию этого пользователя. Но иногда требуется узнать имя пользователя или другие параметры. Проанализируем, как можно получить список всех переменных окружения на сервере:
// Способ получения имени текущего пользователя через системный поток
ВременныйФайл = КаталогВременныхФайлов() + "env_out.tmp";
КомандаСистемы("whoami > " + ВременныйФайл);
Чтение = Новый ЧтениеТекста(ВременныйФайл, КодировкаТекста.Системная);
ИмяПользователяСервера = Чтение.Прочитать();
Чтение.Закрыть();
Сообщить("Сервер 1С работает под пользователем: " + ИмяПользователяСервера);
Если ваша задача — создать кэш, общий для всех пользователей, или если у вас нет доступа к домашним папкам, лучше использовать специализированные места, такие как /tmp/ или путь, возвращаемый функцией КаталогВременныхФайлов().
Для современных версий платформы (8.3.9 и выше) мы рекомендуем использовать встроенные методы, которые скрывают в себе особенности операционных систем:
РабочийКаталогДанныхПользователя() — возвращает путь к папке, где 1С хранит настройки и кэш текущего сеанса. Это самый надежный способ «приземлиться» в нужную папку без ручного формирования пути.КаталогПрограммы() — поможет определить, где установлены бинарные файлы.ПолучитьРазделительПути() — всегда используйте эту функцию вместо жестко прописанных слешей для обеспечения кроссплатформенности, хотя Linux понимает только прямые слеши /.СоздатьКаталог() и НайтиФайлы(). Используйте абсолютные пути..1cv8/1C/1cv8/./opt/ или /var/), убедитесь, что у пользователя 1С есть права на запись в родительскую директорию.HOME — ваш лучший друг для определения путей к данным пользователя.Соблюдение этих простых правил позволит вашему коду работать стабильно в любой среде, избавляя пользователей от загадочных ошибок доступа к файловой системе.