При переходе на операционные системы семейства Linux пользователи 1С часто сталкиваются с тем, что привычный программный код, работающий с файловой системой, начинает вести себя непредсказуемо. Одной из самых коварных проблем является ситуация, когда встроенные функции платформы НайтиФайлы() или УдалитьФайлы() перестают видеть содержимое сетевых ресурсов (Windows-шар), хотя системные утилиты Linux, такие как ls или find, отображают файлы корректно. При этом запись файла методом Записать() может проходить без ошибок. В этой статье мы подробно разберем, почему это происходит и как правильно настроить монтирование сетевых ресурсов для полноценной работы 1С:Предприятие.
Проанализируем типичную ситуацию. Системный администратор монтирует сетевой ресурс Windows в файловую систему Ubuntu, используя стандартную команду mount -t cifs. На первый взгляд всё работает: через консоль файлы видны, права доступа кажутся верными. Однако в 1С следующий код возвращает пустой массив:
МассивНайденныхФайлов = НайтиФайлы("/exchange", "*", Ложь);
// Результат: МассивНайденныхФайлов.Количество() = 0
Более того, попытка удаления файла также может игнорироваться системой без вызова исключения:
Попытка
УдалитьФайлы("/exchange", "test.txt");
Исключение
Сообщить(ОписаниеОшибки()); // Сюда код даже не заходит, но файл остается на месте
КонецПопытки
Выясним причину такого поведения. Платформа 1С:Предприятие при работе в среде Linux взаимодействует с файловой системой более строго, чем стандартные утилиты оболочки. В частности, 1С полагается на уникальные идентификаторы файлов, называемые inode. При монтировании ресурсов Windows через протокол SMB/CIFS сервер Windows не всегда корректно транслирует свои идентификаторы в понятные для Linux номера inode. В результате клиентская ОС может получать дублирующиеся или некорректные номера, что сбивает с толку внутренние механизмы 1С, и она просто «отфильтровывает» такие файлы как некорректные.
Рассмотрим основной способ решения проблемы. Самым важным параметром при монтировании сетевых ресурсов для 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
Разберем по шагам ключевые параметры этой строки:
НайтиФайлы(), гарантируя корректные идентификаторы файлов.vers=1.0 часто имеет проблемы с блокировками и кэшированием.Иногда возникает ситуация, когда файл создается успешно, но метод НайтиФайлы() видит его только спустя некоторое время. Это связано с агрессивным кэшированием в драйвере CIFS. Чтобы исключить рассинхронизацию, проанализируем параметр cache.
По умолчанию Linux кэширует информацию о файлах для повышения производительности. Для задач, где важна актуальность данных (например, обмен файлами между базами), рекомендуется добавить параметр cache=none в строку монтирования. Это заставит систему при каждом вызове НайтиФайлы() напрямую обращаться к сетевому ресурсу, минуя локальный кэш.
Если по каким-то причинам изменить параметры монтирования невозможно (например, из-за политик безопасности), рассмотрим альтернативный способ получения списка файлов. Мы можем использовать мощь системных утилит 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.