Вопрос или проблема
Я пытаюсь выполнить 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// /\\ }" .
Используйте две пары кавычек
-
Не беспокойтесь об обратных слэшах, просто используйте одинарные кавычки внутри двойных кавычек:
ssh [email protected]:"'/home/me/test file'" .
-
(рекомендуется) Вы также можете использовать наоборот, то есть двойные кавычки внутри одинарных кавычек:
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
– локально и удаленно.
-
Локально – Обратите внимание на отсутствие кавычек.
rsync -avu /media/data/The\ Folder* .
-
Удаленно – Обратите внимание на наличие кавычек
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
может неправильно интерпретировать путь и создать новую директорию вместо копирования файлов в указанную.
Основные решения
-
Использование кавычек: Один из наиболее простых способов избежать проблем с пробелами в пути — это использовать кавычки. Например:
rsync -avzP "/mnt/xlses/split/v2/name with space/" "[email protected]:/mnt/xlses/split/v2/name with space/"
-
Экранирование пробелов: Если вы предпочитаете не использовать кавычки, то пробелы можно экранировать с помощью символа обратной косой черты:
rsync -avzP /mnt/xlses/split/v2/name\ with\ space/ "[email protected]:/mnt/xlses/split/v2/name\ with\ space/"
-
Использование опции
--protect-args
или-s
: Эта опция предотвращает изменение аргументов удаленным шеллом. Например:rsync -avzP -s "/mnt/xlses/split/v2/name with space/" "[email protected]:/mnt/xlses/split/v2/name with space/"
-
Без использования обратных слэшей: В некоторых версиях
rsync
можно использовать комбинированные кавычки:rsync -avzP "[email protected]:'/mnt/xlses/split/v2/name with space/'" .
-
Создание символической ссылки на удаленном сервере: Если у вас есть доступ к удаленному серверу, вы можете создать символическую ссылку:
ln -s ~/name\ with\ space ~/name_with_space
Тогда вы сможете использовать:
rsync -avz "[email protected]:~/name_with_space/" .
-
Не клонировать срабатывание пробелов: Уберите завершающий слэш из локального пути, чтобы передать на удаленный сервер полное имя папки:
rsync -avzP /mnt/xlses/split/v2/name\ with\ space "[email protected]:/mnt/xlses/split/v2/"
Заключение
Корректная работа с rsync
и путями, содержащими пробелы, требует тщательной обработки. Используйте кавычки или экранирование пробелов, избегайте сложных пробелов, и применяйте опцию -s
, если это необходимо. Эти советы помогут вам избежать распространенных ошибок и упростят процесс передачи данных между серверами. В будущем, рекомендуется избегать использования пробелов в именах директорий и файлов, чтобы минимизировать возможные проблемы.
Если у вас остались вопросы или требуется дополнительная информация, не стесняйтесь обращаться за помощью!