Как победить НайтиФайлы() и УдалитьФайлы() в 1С на Ubuntu при работе с сетевыми папками

Системный администратор 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе на операционные системы семейства Linux пользователи 1С часто сталкиваются с тем, что привычный программный код, работающий с файловой системой, начинает вести себя непредсказуемо. Одной из самых коварных проблем является ситуация, когда встроенные функции платформы НайтиФайлы() или УдалитьФайлы() перестают видеть содержимое сетевых ресурсов (Windows-шар), хотя системные утилиты Linux, такие как ls или find, отображают файлы корректно. При этом запись файла методом Записать() может проходить без ошибок. В этой статье мы подробно разберем, почему это происходит и как правильно настроить монтирование сетевых ресурсов для полноценной работы 1С:Предприятие.

Анализ проблемы: почему 1С "слепнет" на Linux

Проанализируем типичную ситуацию. Системный администратор монтирует сетевой ресурс Windows в файловую систему Ubuntu, используя стандартную команду mount -t cifs. На первый взгляд всё работает: через консоль файлы видны, права доступа кажутся верными. Однако в 1С следующий код возвращает пустой массив:


МассивНайденныхФайлов = НайтиФайлы("/exchange", "*", Ложь);
// Результат: МассивНайденныхФайлов.Количество() = 0

Более того, попытка удаления файла также может игнорироваться системой без вызова исключения:


Попытка
    УдалитьФайлы("/exchange", "test.txt");
Исключение
    Сообщить(ОписаниеОшибки()); // Сюда код даже не заходит, но файл остается на месте
КонецПопытки

Выясним причину такого поведения. Платформа 1С:Предприятие при работе в среде Linux взаимодействует с файловой системой более строго, чем стандартные утилиты оболочки. В частности, 1С полагается на уникальные идентификаторы файлов, называемые inode. При монтировании ресурсов Windows через протокол SMB/CIFS сервер Windows не всегда корректно транслирует свои идентификаторы в понятные для Linux номера inode. В результате клиентская ОС может получать дублирующиеся или некорректные номера, что сбивает с толку внутренние механизмы 1С, и она просто «отфильтровывает» такие файлы как некорректные.

Решение №1: Использование параметра noserverino

Рассмотрим основной способ решения проблемы. Самым важным параметром при монтировании сетевых ресурсов для 1С является noserverino. Этот флаг заставляет клиентскую операционную систему игнорировать номера inode, передаваемые сервером Windows, и генерировать свои собственные уникальные номера на стороне клиента.

Разберем, как должен выглядеть правильный набор опций в файле /etc/fstab для стабильной работы 1С. Вместо базовой строки монтирования нам нужно использовать расширенную конфигурацию:

Пример строки в fstab:

//192.168.10.100/exchange /exchange cifs user=smbuser,password=pass,uid=usr1cv8,gid=grp1cv8,noserverino,iocharset=utf8,file_mode=0777,dir_mode=0777,vers=2.1 0 0

Разберем по шагам ключевые параметры этой строки:

  1. uid=usr1cv8, gid=grp1cv8 — принудительно назначает владельцем всех файлов пользователя и группу, под которыми запущен сервер 1С. Это критично, так как без этого 1С может не иметь прав на модификацию метаданных.
  2. noserverino — решает проблему с пустым массивом в НайтиФайлы(), гарантируя корректные идентификаторы файлов.
  3. vers=2.1 (или 3.0) — использование современных версий протокола SMB. Старая версия vers=1.0 часто имеет проблемы с блокировками и кэшированием.
  4. iocharset=utf8 — обеспечивает правильное отображение кириллических имен файлов.

Решение №2: Настройка кэширования метаданных

Иногда возникает ситуация, когда файл создается успешно, но метод НайтиФайлы() видит его только спустя некоторое время. Это связано с агрессивным кэшированием в драйвере CIFS. Чтобы исключить рассинхронизацию, проанализируем параметр cache.

По умолчанию Linux кэширует информацию о файлах для повышения производительности. Для задач, где важна актуальность данных (например, обмен файлами между базами), рекомендуется добавить параметр cache=none в строку монтирования. Это заставит систему при каждом вызове НайтиФайлы() напрямую обращаться к сетевому ресурсу, минуя локальный кэш.

Решение №3: Обходной путь через системные команды

Если по каким-то причинам изменить параметры монтирования невозможно (например, из-за политик безопасности), рассмотрим альтернативный способ получения списка файлов. Мы можем использовать мощь системных утилит Linux и передать результат их работы в 1С.

Разберем пример кода, который использует команду find для формирования списка файлов во временном текстовом документе:


ИмяФайлаСписка = ПолучитьИмяВременногоФайла("txt");
// Формируем команду: ищем все файлы в каталоге и записываем их пути в файл
Команда = СтрШаблон("find %1 -maxdepth 1 -type f > %2", ПутьККаталогу, ИмяФайлаСписка);

ЗапуститьПриложение(Команда, , Истина);

ТекстСписок = Новый ТекстовыйДокумент;
ТекстСписок.Прочитать(ИмяФайлаСписка);

Для НомерСтроки = 1 По ТекстСписок.КоличествоСтрок() Цикл
    ПолныйПутьКФайлу = ТекстСписок.ПолучитьСтроку(НомерСтроки);
    // Теперь у нас есть путь, и мы можем работать с объектом Файл
    ТекущийФайл = Новый Файл(ПолныйПутьКФайлу);
    Сообщить("Найден файл: " + ТекущийФайл.Имя);
КонецЦикла;

Этот метод является "костылем", но он работает стабильно, так как утилита find на уровне ядра взаимодействует с файловой системой иначе, чем высокоуровневые методы платформы 1С.

Проблема удаления файлов: права доступа и атрибуты

Проанализируем ситуацию из сообщения пользователя, когда УдалитьФайлы() не выдает ошибку, но файл не удаляется. В Linux при работе с CIFS-ресурсами права доступа часто эмулируются. Если при монтировании не были указаны параметры noperm или не были явно заданы uid/gid сервера 1С, то попытка удаления может быть отклонена драйвером файловой системы на этапе проверки прав, при этом 1С может интерпретировать этот отказ как "файл не найден или уже удален", не вызывая исключения.

Чтобы гарантировать возможность удаления, убедитесь, что в опциях монтирования присутствуют параметры forceuid и forcegid. Они заставляют систему игнорировать права, установленные на сервере Windows, и считать владельцем процесса именно локального пользователя usr1cv8.

Итоговая рекомендация по монтированию:


sudo mount -t cifs //server/share /mnt/point -o user=smbuser,uid=usr1cv8,gid=grp1cv8,noserverino,nocase,cache=none,forceuid,forcegid

Использование параметра nocase также будет полезным, так как Windows нечувствительна к регистру символов, а Linux — чувствителен. Это предотвратит ошибки, когда 1С ищет File.txt, а на диске лежит file.txt.

Соблюдение этих правил позволит вам избежать большинства проблем при работе 1С на Ubuntu с внешними сетевыми ресурсами и сделает работу функций НайтиФайлы() и УдалитьФайлы() такой же предсказуемой, как в среде Windows.

← На главную