Перевод ИТ-инфраструктуры на операционные системы семейства Linux — один из главных трендов автоматизации последних лет. При миграции серверов 1С:Предприятия с Windows на Ubuntu разработчики часто сталкиваются с проблемой неработоспособности привычного кода, завязанного на COM-объекты и Windows-специфичные утилиты. Типичный пример такой задачи — извлечение текстового содержимого из PDF-файлов с помощью консольной утилиты pdftotext.
В этой статье мы подробно разберем, как правильно перенести этот функционал в среду Ubuntu Linux, избавиться от зависимости от Windows-компонентов, настроить права доступа и написать надежный кроссплатформенный код на языке 1С.
Для начала проанализируем, как эта задача обычно решалась в среде Windows. В исходном варианте код выглядит следующим образом:
ТекстКоманды = """" + КаталогПользователя + "hstart.exe"" /NOCONSOLE /WAIT ""pdftotext.exe -layout """ + ПутьКФайлу + """ """ + КаталогПользователя + "Ф420.txt""""";
WshShell = Новый COMОбъект("WScript.Shell");
WshShell.Run(ТекстКоманды, 5, 1);
Текст = Новый ЧтениеТекста(КаталогПользователя+"Ф420.txt", КодировкаТекста.UTF8);
В этой схеме задействовано сразу несколько элементов, которые принципиально не могут работать в операционной системе Linux:
WScript.Shell: Данная технология является частью экосистемы Windows (Windows Script Host) и полностью отсутствует в Linux. Попытка инициализации этого объекта на сервере под управлением Linux вызовет критическую ошибку выполнения.hstart.exe: Вспомогательная программа, которая использовалась для того, чтобы при вызове консольного конвертера у пользователя не «мигало» черное окно командной строки. В серверной среде Linux оконный интерфейс отсутствует в принципе, поэтому подобные утилиты становятся бессмысленными.pdftotext.exe: Исполняемые файлы формата PE (.exe) не могут быть запущены в среде Linux напрямую без использования эмуляторов (например, Wine), что крайне не рекомендуется для серверных решений 1С из-за проблем с производительностью и стабильностью.\ в качестве разделителя каталогов недопустимо — там используется исключительно прямой слэш /.При попытках запустить аналогичную команду в Linux начинающие разработчики часто совершают опасную ошибку — пытаются использовать команду администратора sudo, например:
sudo pdftotext -raw /home/user/4-20.pdf /home/user/4-20.txt
Разберем, почему делать так категорически нельзя:
sudo по умолчанию требует ввода пароля суперпользователя (root) в консоли. При вызове из кода 1С процесс просто «зависнет» в ожидании ввода пароля, заблокировав поток выполнения.pdftotext — это обычный парсер файлов. Ей не требуются системные привилегии для чтения файла и записи результата, если у текущего пользователя операционной системы есть права доступа к целевым папкам.Вывод: запускать утилиту нужно от имени того системного пользователя, под которым работает служба сервера 1С (обычно это пользователь usr1cv8 в Ubuntu).
В операционной системе Ubuntu утилита pdftotext входит в состав стандартного набора инструментов для работы с PDF под названием poppler-utils. Перед тем как вызывать команду из 1С, необходимо один раз установить этот пакет на сервере через терминал.
Выполним установку по шагам:
sudo apt-get update
sudo apt-get install poppler-utils -y
После этого утилита будет установлена глобально в системе, и вызывать ее можно будет простой командой pdftotext из любого каталога без указания полного пути к исполняемому файлу.
При написании кроссплатформенного кода важно учитывать две важные особенности операционной системы Linux:
Регистрозависимость (Case Sensitivity). В отличие от Windows, в Linux файлы Document.pdf, document.pdf и document.PDF — это три абсолютно разных файла. Убедимся, что расширения и имена файлов в коде 1С в точности соответствуют реальным файлам на диске.
Кодировка символов. По умолчанию 1С в Linux работает в кодировке UTF-8. Чтобы утилита pdftotext корректно обработала кириллические символы и сформировала текстовый файл без искажений (так называемых «кракозябр»), рекомендуется принудительно указывать параметр кодировки в параметрах запуска с помощью ключа -enc UTF-8.
Для запуска внешних приложений на платформе 1С существует стандартный кроссплатформенный метод ЗапуститьПриложение(). Он работает одинаково хорошо как на Windows, так и на Linux.
Синтаксис метода выглядит так:
ЗапуститьПриложение(<СтрокаКоманды>, <ТекущийКаталог>, <ДождатьсяЗавершения>, <КодВозврата>)
Для решения нашей задачи критически важен третий параметр — ДождатьсяЗавершения. Установив его в значение Истина, мы заставляем платформу приостановить выполнение кода 1С до тех пор, пока утилита pdftotext не закончит конвертацию и не запишет итоговый файл на диск. Это прямой аналог ключа /WAIT из Windows-версии.
Рассмотрим готовый программный код, который определяет операционную систему сервера, корректно формирует пути и запускает конвертацию PDF-документа в текстовый файл с последующим чтением его содержимого.
// Определяем разделитель путей в зависимости от ОС
РазделительПути = ПолучитьРазделительПути();
// Пути к исходному PDF и будущему текстовому файлу
// Рекомендуется использовать временный каталог 1С, к которому у процесса usr1cv8 точно есть права на запись
ПутьКФайлуPDF = "/home/user/documents/report_2023.pdf";
КаталогВременный = КаталогВременныхФайлов();
ПутьКФайлуTXT = КаталогВременный + "converted_pdf_data.txt";
// Параметры утилиты pdftotext:
// -layout : сохраняет оригинальное форматирование и структуру колонок/таблиц
// -enc UTF-8 : гарантирует корректную выгрузку кириллицы в UTF-8
СтрокаКоманды = "pdftotext -layout -enc UTF-8 """ + ПутьКФайлуPDF + """ """ + ПутьКФайлуTXT + """";
КодВозврата = Неопределено;
Попытка
// Запуск утилиты в режиме ожидания (Истина)
ЗапуститьПриложение(СтрокаКоманды, , Истина, КодВозврата);
Исключение
ВызватьИсключение "Не удалось запустить утилиту pdftotext. Проверьте, установлен ли пакет poppler-utils на сервере.";
КонецПопытки;
Если КодВозврата = 0 Тогда
// Файл успешно создан, приступаем к чтению содержимого
ФайлТекста = Новый Файл(ПутьКФайлуTXT);
Если ФайлТекста.Существует() Тогда
Чтение = Новый ЧтениеТекста(ПутьКФайлуTXT, КодировкаТекста.UTF8);
СодержимоеPDF = Чтение.Прочитать();
Чтение.Закрыть();
// Здесь выполняется логика разбора полученного текста
// ...
// Обязательно удаляем временный файл после обработки, чтобы не засорять диск сервера
Попытка
УдалитьФайлы(ПутьКФайлуTXT);
Исключение
// Запись в журнал регистрации, если файл заблокирован другим процессом
ЗаписьЖурналаРегистрации("КонвертацияPDF", УровеньЖурналаРегистрации.Предупреждение, , ,
"Не удалось удалить временный файл: " + ПутьКФайлуTXT);
КонецПопытки;
Иначе
ВызватьИсключение "Конвертация завершена успешно, но результирующий файл не найден.";
КонецЕсли;
Иначе
ВызватьИсключение "Ошибка выполнения утилиты pdftotext. Код ошибки возврата ОС: " + КодВозврата;
КонецЕсли;
Иногда после переноса кода разработчики замечают, что текстовый файл создается пустым или текст в нем отображается некорректно. Разберем основные причины такого поведения:
pdftotext извлекает только встроенный текстовый слой. Если документ был отсканирован без распознавания (OCR), то внутри файла находится обычная картинка. В этом случае утилита вернет пустой текст. Для решения этой проблемы потребуется использовать полноценные системы распознавания символов (например, Tesseract OCR)./home/user/...), служба 1С (usr1cv8) может не иметь прав на чтение этого каталога. Рекомендуется переносить обрабатываемые файлы в общие каталоги обмена или использовать временную папку 1С.Использование метода ЗапуститьПриложение() совместно со штатной утилитой pdftotext из пакета poppler-utils позволяет создать быстрое, производительное и полностью бесплатное решение для парсинга документов PDF на серверах под управлением Linux, полностью отказавшись от устаревших Windows-зависимых механизмов.