Как исправить ошибку 'Quote command returned error' при перемещении файлов по FTP в 1С?

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

При попытке переместить файлы внутри FTP-каталога с использованием платформы 1С:Предприятие 8.3 пользователи могут столкнуться с ошибкой «Ошибка открытия файла обмена Ошибка при вызове метода контекста (Переместить): Ошибка работы с Интернет: ftp://*.68:44 Quote command returned error». Эта ошибка является достаточно распространенной и указывает на то, что FTP-сервер отклонил команду перемещения файла. Давайте рассмотрим основные причины возникновения этой проблемы и разберем по шагам, как ее диагностировать и устранить.

Проблема пользователя и исходный код

Пользователь столкнулся с проблемой при попытке переместить XML-файлы, которые были успешно загружены и обработаны в 1С. Исходный код, вызывающий ошибку, выглядит следующим образом:


ФТПХост         = "*.68";
ФТППорт         = "44";
ФТППользователь = "login";     
ФТППароль       = "password";
ФТПКаталог      = "/obmen/";
ФТП = Новый FTPСоединение(ФТПХост,ФТППорт, ФТППользователь, ФТППароль);
ФТП.УстановитьТекущийКаталог(ФТПКаталог);
Файлы = ФТП.НайтиФайлы(ФТП.ТекущийКаталог(), "*.xml", Ложь);
Если Файлы.Количество() > 0 Тогда
    Для каждого Файл Из Файлы Цикл
        ОбработкаВыгрузкиXML = Обработки.УниверсальныйОбменДаннымиXML.Создать();
        ОбработкаВыгрузкиXML.РежимОбмена     = "Загрузка";
        ОбработкаВыгрузкиXML.ИмяФайлаОбмена  = ФТП.ТекущийКаталог() + Файл.Имя;
        ОбработкаВыгрузкиXML.ВыполнитьЗагрузку();
        ОбработкаВыгрузкиXML = "";
        
        Попытка
            ФТП.Переместить(ФТП.ТекущийКаталог() + Файл.Имя, ФТП.ТекущийКаталог() + "Archive/" + Файл.Имя);
        Исключение
            Сообщить(ОписаниеОшибки());
        КонецПопытки;
    КонецЦикла;
КонецЕсли;

В данном коде после успешной загрузки XML-файла осуществляется попытка переместить его из текущего каталога /obmen/ в подкаталог /obmen/Archive/. Именно на строке ФТП.Переместить(...) возникает указанная ошибка.

Основная причина: Проблемы с правами доступа на FTP-сервере

Как показывает практика и обсуждение на форуме, наиболее частой причиной ошибки «Quote command returned error» являются недостаточные права доступа для пользователя на FTP-сервере. Даже если кажется, что у пользователя login есть права на чтение и запись, для выполнения операции перемещения (которая на самом деле является переименованием или комбинацией копирования и удаления) требуются дополнительные права, такие как:

  1. Права на переименование файлов в исходном каталоге.
  2. Права на удаление файлов из исходного каталога.
  3. Права на создание/запись файлов в целевом каталоге.
  4. Права на создание каталогов (если целевой каталог Archive не существует).

Давайте проверим этот аспект, чтобы выяснить истинную причину:

  1. Проверка прав с помощью стороннего FTP-клиента: Мы настоятельно рекомендуем использовать специализированный FTP-клиент, например, FileZilla или WinSCP, для проверки прав. Авторизуйтесь под тем же пользователем (в нашем случае login) и попробуйте выполнить следующие операции:

    • Попытайтесь создать новый файл в каталоге /obmen/.
    • Попытайтесь создать новый файл в каталоге /obmen/Archive/ (если он существует) или создать сам каталог Archive.
    • Попытайтесь переименовать любой файл в каталоге /obmen/.
    • Попытайтесь переместить файл из /obmen/ в /obmen/Archive/.
    • Попытайтесь удалить файл из /obmen/.

    Если любая из этих операций завершается ошибкой (например, "Permission denied" или "Access denied"), это является явным указанием на проблему с правами доступа. Вам потребуется обратиться к администратору FTP-сервера для настройки соответствующих разрешений для пользователя login.

  2. Подтверждение проблемы на форуме: Автор темы подтвердил, что после проверки с файловым менеджером перемещение и даже удаление файлов не происходит. Это служит веским доказательством того, что проблема связана именно с недостаточными правами доступа пользователя login на FTP-сервере, а не с кодом 1С.

Особенности работы FTP-сервера и поддержка команд

Помимо прав доступа, причиной ошибки «Quote command returned error» может быть специфика работы самого FTP-сервера и его настройки. Команда Переместить в 1С, как правило, использует FTP-команды RNFR (Rename From) и RNTO (Rename To) для выполнения операции перемещения/переименования. Рассмотрим другие возможные причины, связанные с конфигурацией сервера:

  1. Отсутствие поддержки команды RENAME (RNFR/RNTO): Некоторые FTP-серверы могут быть настроены таким образом, что команда переименования отключена или не поддерживается для определенных каталогов или пользователей. В таких случаях сервер возвращает ошибку, подобную "500 Command not understood" или "550 Requested action not taken". Вам следует обратиться к администратору для проверки конфигурации FTP-сервера и убедиться, что команды переименования разрешены.

  2. Блокировка файла: Если файл активно используется другим процессом на FTP-сервере (например, он только что был загружен 1С и еще не полностью освобожден сервером или другим приложением), FTP-сервер может отказать в операции перемещения. Некоторые серверы временно блокируют файлы во время или сразу после загрузки. Это может быть связано с антивирусными проверками на сервере или особенностями его файловой системы.

  3. Особенности FTP-сервера при загрузке (скрытие файлов): Определенные FTP-серверы могут загружать файлы под временными именами (например, добавляя расширение .part или начиная имя файла с .in.), а затем переименовывать их только после полного завершения загрузки. Если 1С пытается переместить файл до того, как он окончательно "появится" под своим основным именем, это также может привести к ошибке "файл не найден" или «Quote command returned error». Проверьте логи сервера на предмет таких операций и, при необходимости, добавьте небольшую задержку в коде 1С перед перемещением.

  4. Настройки пассивного режима (Passive Mode): Хотя это реже влияет непосредственно на команду RENAME, общие проблемы с FTP-соединением, включая ошибки команд, могут быть связаны с активным/пассивным режимом передачи данных. По умолчанию FTPСоединение в 1С использует активный режим. Если ваша сетевая инфраструктура или FTP-сервер находятся за брандмауэром и требуют пассивного режима, попробуйте явно установить свойство ПассивныйРежим = Истина при создании объекта FTPСоединение:

    
    ФТП = Новый FTPСоединение(ФТПХост, ФТППорт, ФТППользователь, ФТППароль, Истина); // Истина включает пассивный режим
    
  5. Таймаут соединения: В некоторых случаях ошибка может быть связана с истечением таймаута соединения. Если операция перемещения занимает слишком много времени из-за больших файлов или медленной сети, соединение может быть разорвано до завершения. Вы можете попробовать увеличить значение таймаута в конструкторе объекта FTPСоединение:

    
    ФТП = Новый FTPСоединение(ФТПХост, ФТППорт, ФТППользователь, ФТППароль, Ложь, 60); // Таймаут 60 секунд
    

    Значение по умолчанию обычно составляет 30 секунд. Убедитесь, что таймаут достаточен для выполнения всех операций.

  6. Файлы удаляются сразу после загрузки: На некоторых хостингах или FTP-серверах существуют ограничения на типы файлов, их размер или местоположение. Если загруженный файл не соответствует этим требованиям (например, содержит вредоносный код, превышает лимит по размеру), он может быть автоматически удален сразу после загрузки, что сделает его недоступным для перемещения.

Варианты формирования путей

Хотя автор темы перепроверил пути, иногда некорректное формирование пути может быть причиной ошибки «Quote command returned error». Метод ФТП.Переместить() ожидает полный путь к исходному файлу и полный путь к целевому файлу, включая их имена.

Один из вариантов, предложенных на форуме, это использование:

ФТП.Переместить(Файл.ПолноеИмя, "/Archive/" + Файл.Имя);

В данном случае, если Файл.ПолноеИмя уже содержит полный путь до файла (например, /obmen/файл.xml), а целевой каталог Archive находится не в корне FTP-сервера, а внутри текущего каталога /obmen/, то путь "/Archive/" + Файл.Имя будет некорректным. Он будет означать попытку переместить файл в каталог Archive, расположенный прямо в корне FTP-сервера, а не внутри /obmen/.

Корректнее будет формировать пути таким образом, чтобы они однозначно указывали на расположение относительно корня FTP-сервера, либо относительно текущего каталога, если это явно поддерживается сервером и методом 1С. В приведенном примере более надежным будет следующий подход:


// Предполагаем, что ФТП.ТекущийКаталог() вернул "/obmen/"
// Исходный файл: "/obmen/файл.xml"
// Целевой файл:  "/obmen/Archive/файл.xml"
ФТП.Переместить(ФТП.ТекущийКаталог() + Файл.Имя, ФТП.ТекущийКаталог() + "Archive/" + Файл.Имя);

Если же вы используете свойство Файл.ПолноеИмя, убедитесь, что оно корректно формируется для FTP-сервера и что целевой путь соответствует реальной структуре:


// Вариант с заменой подстроки, если Файл.ПолноеИмя уже содержит базовый каталог
// Например, если Файл.ПолноеИмя = "/obmen/файл.xml"
// А ФТПКаталог = "/obmen/"
ЦелевойПуть = СтрЗаменить(Файл.ПолноеИмя, ФТПКаталог, ФТПКаталог + "Archive/");
ФТП.Переместить(Файл.ПолноеИмя, ЦелевойПуть);

Всегда внимательно проверяйте окончательный вид строк, которые передаются в метод ФТП.Переместить(), чтобы избежать ошибок, связанных с некорректным синтаксисом путей.

Альтернативные подходы: копирование через временный файл и удаление

Если команда Переместить (которая по сути является переименованием на FTP-сервере) не работает из-за ограничений прав или отсутствия поддержки команды, можно попробовать реализовать операцию перемещения в несколько этапов, используя временное локальное хранилище. Этот подход требует, чтобы у 1С были права на запись во временный каталог на локальной машине, а у FTP-пользователя — на чтение исходного файла на FTP, запись нового файла в целевом каталоге на FTP и удаление исходного файла на FTP.

Алгоритм действий будет следующим:

  1. Получить (скачать) исходный файл с FTP-сервера во временный локальный файл. Для этого используем метод FTPСоединение.Получить().
  2. Записать (загрузить) этот временный локальный файл в целевой каталог на FTP-сервере. Для этого используем метод FTPСоединение.Записать().
  3. Удалить исходный файл с FTP-сервера. Для этого используем метод FTPСоединение.Удалить().
  4. Удалить временный локальный файл с компьютера, чтобы не оставлять следов.

Рассмотрим пример кода для такого сценария:


ИмяИсходногоФайлаНаФТП = ФТП.ТекущийКаталог() + Файл.Имя;
ИмяЦелевогоКаталогаНаФТП = ФТП.ТекущийКаталог() + "Archive/";
ИмяЦелевогоФайлаНаФТП = ИмяЦелевогоКаталогаНаФТП + Файл.Имя;

// Создаем временное имя файла на локальном компьютере
КаталогВременныхФайлов = ПолучитьКаталогВременныхФайлов();
ИмяВременногоЛокальногоФайла = КаталогВременныхФайлов + Файл.Имя;

Попытка
    // Шаг 1: Скачиваем файл с FTP на локальную машину
    ФТП.Получить(ИмяВременногоЛокальногоФайла, ИмяИсходногоФайлаНаФТП);
    
    // Шаг 2: Загружаем файл с локальной машины обратно на FTP в новый каталог
    ФТП.Записать(ИмяВременногоЛокальногоФайла, ИмяЦелевогоФайлаНаФТП);
    
    // Шаг 3: Если загрузка прошла успешно, удаляем исходный файл с FTP
    ФТП.Удалить(ИмяИсходногоФайлаНаФТП);
    
    // Шаг 4: Удаляем временный файл с локальной машины
    УдалитьФайлы(ИмяВременногоЛокальногоФайла);
    
Исключение
    Сообщить("Ошибка при копировании/перемещении файла через временное хранилище: " + ОписаниеОшибки());
КонецПопытки;

Как видите, этот метод более сложен и может быть медленнее, так как требует передачи данных туда и обратно. Важно отметить, что если даже ФТП.Удалить() не работает, как это было в случае автора темы, то проблема лежит глубоко в правах доступа FTP-пользователя или настройках сервера, и этот обходной путь также не поможет, пока не будут исправлены права. В этом случае, единственным решением будет настройка прав на самом FTP-сервере. Чтобы упростить настройку выгрузки файлов, можно использовать готовый инструмент для организации файлового обмена по FTP.

Критически важный шаг: Анализ логов FTP-сервера

Самый информативный и точный способ диагностики любой проблемы с FTP-сервером — это анализ его логов. Логи FTP-сервера (например, Pure-FTPd, ProFTPD, vsftpd) содержат детальную информацию о каждой полученной команде, ответе сервера и причинах возможных ошибок.

Обратитесь к администратору FTP-сервера с просьбой предоставить логи за период выполнения вашей операции. В логах вы сможете увидеть:

  1. Какие команды (RNFR, RNTO, DELE, STOR и т.д.) были получены от клиента 1С.
  2. Какой код ответа FTP-сервер вернул на каждую команду (например, 250 Rename successful, 550 File unavailable, 500 Command not understood).
  3. Конкретное сообщение об ошибке на стороне сервера, которое часто более информативно, чем общее «Quote command returned error» из 1С.

Анализ логов позволит точно определить, на каком этапе происходит сбой и почему сервер отклоняет команду перемещения. Это является ключом к пониманию и окончательному решению проблемы.

Заключение

В большинстве случаев ошибка «Quote command returned error» при перемещении файлов по FTP в 1С указывает на проблемы с правами доступа для пользователя на FTP-сервере или на ограничения, связанные с поддержкой определенных команд на самом сервере. Мы рекомендуем последовательно проверить все перечисленные шаги, начиная с диагностики прав доступа с помощью стороннего FTP-клиента, а затем переходя к анализу конфигурации FTP-сервера и его логов. Взаимодействие с администратором FTP-сервера будет ключевым для успешного разрешения этой проблемы. После устранения проблем с правами или конфигурацией сервера, ваш код 1С для перемещения файлов должен заработать корректно.

← На главную