Как использовать rsync по ssh, когда названия директорий содержат пробелы

Вопрос или проблема

Я пытаюсь выполнить rsync с одного сервера на другой. Серверы имеют одинаковую структуру директорий, но у меня возникли проблемы с тем, чтобы удаленный сервер правильно распознал имя пути, когда в нем есть пробел.

Вот детали

Локальная директория

mnt/xlses/split/v2/name with space

Удаленная директория

mnt/xlses/split/v2/name with space

Я пробовал всё, что мог найти, последняя попытка была такой:

rsync --size-only -avzPe ssh  /mnt/xlses/split/v2/name\ with\ space/ [email protected]:/mnt/xlses/split/v2/"name with space"

Когда это выполняется, первой вещью, о которой он сообщает, является то, что он создает новую директорию

Я прерываю его и вижу, что есть новая директория

mnt/xlses/split/v2/name

все мои файлы находятся в этой директории

Я ожидал, что они будут в

mnt/xlses/split/v2/name with space

Попробуйте

rsync -s --size-only -avzP  "/mnt/xlses/split/v2/name with space/" "[email protected]:/mnt/xlses/split/v2/name with space"

Из man rsync (обновлено в 2023):

--secluded-args, -s

Эта опция отправляет все имена файлов и большинство параметров на удаленный rsync через протокол (не через командную строку удаленной оболочки), что позволяет избежать изменения их удаленной оболочкой. Шаблоны расширяются на удаленном хосте rsync вместо оболочки.

[…]

Эта опция раньше называлась --protect-args (до версии 3.2.6), и это старое имя по-прежнему может использоваться (хотя указание его как -s всегда является самым простым и совместимым выбором).

Это работает в bash: Экранируйте пробелы обратным слэшом и затем используйте кавычки:

rsync -avuz [email protected]:"/media/Music/Heavy\ Metal/Witch\ Mountain/*" .

Или если у вас есть путь в переменной $remote_path, пробелы могут быть экранированы с помощью замены:

rsync -avuz [email protected]:"${remote_path// /\\ }" .

Используйте две пары кавычек

  1. Не беспокойтесь об обратных слэшах, просто используйте одинарные кавычки внутри двойных кавычек:

    ssh [email protected]:"'/home/me/test file'" .
    
  2. (рекомендуется) Вы также можете использовать наоборот, то есть двойные кавычки внутри одинарных кавычек:

    ssh [email protected]:'"/home/me/test file"' .
    

Второй вариант лучше, потому что вы можете использовать шаблоны на сервере (потому что одинарные кавычки не будут расширяться на клиенте). Я делаю это, когда пытаюсь rsync несколько файлов с одинаковым префиксом.


Дополнительная информация

Шаблоны на стороне сервера

Если вы хотите, чтобы * интерпретировался на сервере, а не на клиенте, * должен находиться внутри одной из 2 пар кавычек. Я нахожу это нелогичным, потому что логически внешняя пара кавычек экранирует интерпретацию клиента, в то время как внутренняя пара кавычек экранирует интерпретацию сервера.

Защита аргументов

Преимущество, по сравнению с --protect-args решением, заключается в том, что у вас на самом деле нет ограничений --protect-args, так что вы можете использовать специальные символы, такие как ~ или $. Так что вы можете написать:

rsync host:'"$HOME/test file"' .

или

rsync host:'~"/test file"' .

Обратите внимание, что тильда (~) в последнем примере должна быть снаружи двойных кавычек.

Вы можете поместить одну из пар кавычек вокруг всей части username@host:file (например, ssh "[email protected]:'/home/me/test file'" .)

Попробуйте таким образом:

rsync --size-only -avzP /mnt/xlses/split/v2/name\ with\ space [email protected]:/mnt/xlses/split/v2/

Я убрал конечный слэш / из путь к исходной директории. Это заставит rsync скопировать директорию и все её содержимое, что означает, что rsync позаботится о правильном получении имени на удаленном хосте (что он и сделает), вместо вас.

Я понимаю, что это старый вопрос, но я думал, что добавлю к существующему объему знаний.

Я использовал rsync с несколькими папками с пробелами, и это работает. У меня есть папки номерованные с 1 до 10, как ниже:

  • The\ Folder1
  • The\ Folder2
  • The\ Folder3
  • ..
  • The\ Folder10

2 случая, когда вам нужно использовать rsync – локально и удаленно.

  1. Локально – Обратите внимание на отсутствие кавычек.

    rsync -avu /media/data/The\ Folder* .
    
  2. Удаленно – Обратите внимание на наличие кавычек

    rsync -avu [email protected]:"/media/data/The\ Folder*" .
    

Из man-страниц rsync:

   Если вам нужно передать имя файла, которое содержит пробелы, вы можете
   либо указать опцию --protect-args (-s), либо вам нужно экранировать
   пробелы таким образом, чтобы удаленная оболочка их поняла. Например:

          rsync -av host:'file\ name\ with\ spaces' /dest

В общем, заключите аргумент в кавычки и экранируйте пробелы в аргументе. В приведенном вами примере попробуйте:

rsync --size-only -avzP  "/mnt/xlses/split/v2/name\ with\ space/" "[email protected]:/mnt/xlses/split/v2/name\ with\ space"

На macOS мне пришлось обычно экранировать первый путь, и второй путь экранирован + кавычки. Пример:

rsync -avhu VirtualBox\ VMs/Windows\ 10 [email protected]:"/Users/bob/VirtualBox\ VMs/"

Это единственное сочетание, которое работало с пробелами на macOS. Обе машины – mac.

Я собираюсь ответить на этот вопрос сам, хотя кто-то другой может сделать это лучше.

По всей видимости, настройка на машине назначения влияет на то, как парсятся аргументы, и у нас должна быть какая-то настройка, которая затрудняет использование кавычек или слэшей для экранирования пробелов, но мы можем использовать шаблоны, так что я сделал это

rsync --size-only -avzP  /mnt/xlses/split/v2/name\ with\ space/ [email protected]:/mnt/xlses/split/v2/name*

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

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

Попробуйте так:

find /path/ -exec rsync -A -X -av -r -s root@xxxx:/path/ {} \;

В зависимости от ситуации, быстрый вариант – создать символическую ссылку на удаленной системе:

user@remote$ ln -s ~/name\ with\ space/ ~/name_with_space

Затем используйте флаг -L в rsync, который указывает следовать содержимому директории:

user@local$ rsync -avz -L user@remote:~/name_with_space/ ~/name\ with\ space

rsync /mnt/xlses/split/v2/name\\\ with\\\ space/ [email protected]:/mnt/xlses/split/v2/name\\\ with\\\ space

двойное экранирование тоже работает

Ответ или решение

Как использовать rsync через ssh, если имена директорий содержат пробелы

Использование rsync для синхронизации файлов и директорий между серверами — это мощный инструмент для IT-специалистов. Однако при работе с директориями, содержащими пробелы, могут возникнуть сложности. Рассмотрим подробно, как правильно настроить команду rsync, чтобы избежать ошибок при указании путей.

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

Когда вы пытаетесь выполнить команду rsync, путь к директории, содержащей пробелы, может вызвать ошибки в обработке. Например, если ваш локальный и удаленный путь выглядит следующим образом:

  • Локальная директория: /mnt/xlses/split/v2/name with space/
  • Удаленная директория: /mnt/xlses/split/v2/name with space/

Используя пробел в имени папки без соответствующей обработки, rsync может неправильно интерпретировать путь и создать новую директорию вместо копирования файлов в указанную.

Основные решения

  1. Использование кавычек: Один из наиболее простых способов избежать проблем с пробелами в пути — это использовать кавычки. Например:

    rsync -avzP "/mnt/xlses/split/v2/name with space/" "[email protected]:/mnt/xlses/split/v2/name with space/"
  2. Экранирование пробелов: Если вы предпочитаете не использовать кавычки, то пробелы можно экранировать с помощью символа обратной косой черты:

    rsync -avzP /mnt/xlses/split/v2/name\ with\ space/ "[email protected]:/mnt/xlses/split/v2/name\ with\ space/"
  3. Использование опции --protect-args или -s: Эта опция предотвращает изменение аргументов удаленным шеллом. Например:

    rsync -avzP -s "/mnt/xlses/split/v2/name with space/" "[email protected]:/mnt/xlses/split/v2/name with space/"
  4. Без использования обратных слэшей: В некоторых версиях rsync можно использовать комбинированные кавычки:

    rsync -avzP "[email protected]:'/mnt/xlses/split/v2/name with space/'" .
  5. Создание символической ссылки на удаленном сервере: Если у вас есть доступ к удаленному серверу, вы можете создать символическую ссылку:

    ln -s ~/name\ with\ space ~/name_with_space

    Тогда вы сможете использовать:

    rsync -avz "[email protected]:~/name_with_space/" .
  6. Не клонировать срабатывание пробелов: Уберите завершающий слэш из локального пути, чтобы передать на удаленный сервер полное имя папки:

    rsync -avzP /mnt/xlses/split/v2/name\ with\ space "[email protected]:/mnt/xlses/split/v2/"

Заключение

Корректная работа с rsync и путями, содержащими пробелы, требует тщательной обработки. Используйте кавычки или экранирование пробелов, избегайте сложных пробелов, и применяйте опцию -s, если это необходимо. Эти советы помогут вам избежать распространенных ошибок и упростят процесс передачи данных между серверами. В будущем, рекомендуется избегать использования пробелов в именах директорий и файлов, чтобы минимизировать возможные проблемы.

Если у вас остались вопросы или требуется дополнительная информация, не стесняйтесь обращаться за помощью!

Оцените материал
Добавить комментарий

Капча загружается...