При использовании SSH для подключения rsync к удаленному серверу, как избежать пробелов и т.п. на удаленном пути? Простая обратная косая черта убирает пробел для локального приглашения bash, но на удаленной машине пробел затем читается как разрыв в пути, тем самым отмечая конец этого пути.
Итак, когда я это сделаю rsync -avz /path/to/source/some\ dir/ user@host.tld:/path/to/dest/some\ dir/
происходит то, что удаленный сервер читает это как /path/to/dest/some/
и поскольку он не может найти это место назначения удаленно, потому что фактическим местом назначения является «некоторый каталог», а не просто «какой-то».
Если я попробую ту же команду и избегу обратной косой черты и пробела, чтобы пропустить локальную подсказку bash и сохранить обратную косую черту для удаленного сервера (всего три обратной косой черты: /path/to/dest/some\\\ dir/
), он действительно отправляет обратную косую черту на удаленный сервер, но удаленный сервер затем интерпретирует путь как /path/to/dest/some\/
скорее, чем /path/to/dest/some\ dir/
все еще удаляя пробел и символы после него.
Если я попытаюсь заключить путь в кавычки, он будет вести себя примерно так же, фактически обрезая путь в пространстве. Так что это тоже работает, только чтобы обойти локальную подсказку bash.
Изначально я использовал путь, в котором был сегмент «-» (пробел-дефис-пробел), и удаленный сервер возвращал ошибку rsync: on remote machine: -: unknown option
именно с этого в первую очередь началось все это стремление к побегу из космоса.
Итак, что я должен сделать, чтобы это работало правильно с удаленным сервером, без необходимости удалять пробелы или другие ошибочные символы, такие как дефисы, с удаленного пути?
На машине-инициаторе rsync
создает командную строку, которая вызывает цель rsync на удаленном компьютере, а затем отправляет эту командную строку с помощью ssh .... как одна строка. Эта единственная строка передается в оболочку для анализа, разделения на аргументы и выполнения. rsync
. Я понятия не имею, почему это делается, вместо того, чтобы упаковать аргументы (уже разделенные, развернутые и не заключенные в кавычки) в какой-то бинарно-безопасный контейнер для удаленного rsync.
Это означает, что ваши аргументы будут проанализированы два разные снаряды, цитата и реквотировать соответственно. Обычно я заключаю каждый аргумент в двойные кавычки, а затем все выражение в одинарные кавычки. иногда этого недостаточно или это может быть сложно, если вы хотите, чтобы одно и то же выражение использовалось локально и удаленно.
В таких случаях я обычно устанавливаю некоторые программные ссылки с простыми именами без пробелов и полностью в формате ASCII и использую их.
Точечный ответ:
Используйте -s (защитить аргументы) и заключите свой путь в кавычки:
rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"
Работает как с пробелами, так и с дефисами.
Вы были на правильном пути, когда сказали:
Если я попробую ту же команду и избегу обратной косой черты и пробела, чтобы пропустить локальную подсказку bash и сохранить обратную косую черту для удаленного сервера
Вот способ, который мне проще всего сделать:
rsync -av dir\ with\ spaces/ server.tld:"dir\ with\ spaces"
и этот способ тоже работает.
rsync -av dir\ with\ spaces/ server.tld:dir\\\ with\\\ spaces
Можете ли вы опубликовать точный результат и любые обнаруженные вами ошибки?
Вы можете заменить rsync
с обеих сторон скриптом-оболочкой?
$ sudo su -
# cd /usr/bin
# mv rsync rsync.real
# cat <<'EOF' >rsync
#!/bin/bash
logfile=/home/yourname/rsync.log
date >> "$logfile"
i=1
for arg in "$@"; do
echo "arg $i: $arg" >> "$logfile"
i=$((i+1))
done
rsync.real "$@"
EOF
# chmod +x rsync
Затем снова запустите rsync, и он должен доказать, что этот способ экранирования работает, например
Сторона клиента:
Sun Feb 13 13:48:12 EST 2011
1: -av
2: dir with spaces/
3: server:dir\ with\ spaces
На стороне сервера:
Sun Feb 13 13:48:13 EST 2011
1: --server
2: -vlogDtpre.iL
3: .
4: dir with spaces
В приведенном выше примере тот факт, что 4-й аргумент на сервере (dir with spaces
) в одной строке говорит о том, что цитирование работает правильно.
Если это не помогает, попробуйте перезапустить rsync -v
, или rsync -vv
, или rsync -vvv
. Это даст вам дополнительную отладочную информацию.
Два других глупых предложения:
-a
или -r
вариант? Вы можете просто заключить свой путь в кавычки.