Уникнення пробілів у віддаленому контурі при використанні rsync через віддалене з'єднання SSH


10

Використовуючи 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/все-таки знімати простір та символи після нього.

Якщо я спробую обернути шлях цитатами, він поводиться приблизно так само, ефективно відрізаючи шлях у просторі. Тож це також працює лише для того, щоб пройти повз місцевий підказ.

Спочатку я використовував шлях, який мав у ньому сегмент "-" (простір-дефіс-простір), і віддалений сервер повертав помилку rsync: on remote machine: -: unknown option, саме з цього і почалося все це пробіг в космосі.

Отже, що я повинен зробити, щоб це працювало належним чином з віддаленим сервером, без необхідності видаляти пробіли чи інші помилкові символи, як дефіси з віддаленого шляху?


1
Спробуйте обидва та подвійні лапки.
jftuga

Хав'єр також згадав про це, і це в кінцевому підсумку спрацювало, тому я вставив свій сегмент робочого коду у відповідь на його відповідь.
purefusion

@purefusion Розгляньте як маркування відповіді Грегорі правильною. У -sрозглядається питання без необхідності застосовувати подвійний втечу вручну.
m000

Відповіді:


9

На ініціаторній машині rsyncстворює командний рядок, який викликає ціль rsync на віддаленій машині, а потім надсилає цей командний рядок, використовуючи ssh .... як єдину рядок . Цей єдиний рядок передається оболонці для розбору, розділення на аргументи та виконання rsync. Я поняття не маю, чому це робиться, замість упаковки (вже розщепленого, розширеного та не цитованого) аргументів у якийсь бінарний безпечний контейнер у віддалений rsync.

Це означає, що ваші аргументи будуть проаналізовані двома різними оболонками, відповідно цитувати та реквізувати . Зазвичай я обертаю кожен аргумент подвійними цитатами, а потім цілим виразом на одноцитатах. іноді цього недостатньо, або це може бути складно, якщо ви хочете, щоб той самий вираз використовувався локально та віддалено.

У таких випадках я зазвичай встановлюю кілька м'яких посилань з простими, без пробілів, усіма іменами ASCII і використовую це.


8
А переможець - ... одиничні + подвійні цитати! Можливо, це по-різному на кожному сервері, тому якщо інші відповіді для деяких людей не працюють, можливо, цей буде. Ось успішний код, який я використав на віддаленій стороні команди rsync:'user@host.tld:"/path/to/dest/some\ dir/"'
purefusion

Тепер напрошується питання, чому ЦЕ працює ЦЕ (на моєму сервері), але не будь-який з інших варіантів (просто загортаючи шлях у подвійні лапки або використовуючи потрійні риски)? Я запускаю CentOS 5, якщо це має значення.
purefusion

Це не повинно бути необхідним. Як ти це працюєш? Можливо, ви запускаєте його за допомогою evalабо через дзвінок до функції?
Мікель

Ви не використовуєте одинарні плюс подвійні лапки. Ви використовуєте одиничні котирування плюс подвійні лапки плюс втечі зворотної косої риски. ТРИ рівень цитування. Це повинно бути зайвим. Я знову запитую: як ти це працюєш ?
Мікель

@Javier "Я поняття не маю, чому це робиться". Імовірно, що розширення тильди працює.
Мікель

2

Ви були на правильному шляху, коли сказали:

Якщо я спробую виконати ту саму команду і уникнути зворотної косої риски та місця, щоб пройти місцевий підказчик 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. Це дасть вам додаткову інформацію про налагодження.

Дві інші дурні пропозиції:

  • другий сервер - це сервер Linux, і яка там ваша оболонка за замовчуванням?
    • можливо, це розширення назв файлів інакше, ніж ви очікували
  • ви забули додати -aабо -rваріант?
    • Я не можу сказати, не побачивши вашого результату

Як згадується в деталях запитання, я дійсно спробував обидва ваші перші два способи. Можливо, вони просто не працюють на моєму сервері. Я також не відчував, як возитися зі скриптами для обгортки. Я намагаюся триматися подалі від злому / usr / bin / ... У будь-якому випадку, інший більш специфічний спосіб цитування дійсно працював для мене, тому, можливо, саме так працює мій сервер. Ваші пропозиції, безумовно, можуть бути життєздатними для людей на інших серверах або тих, хто не працює на CentOS, якщо ОС все-таки є частиною проблеми.
purefusion

То як це ти процитував, щоб він працював?
Мікель

Ви залишаєте важливу деталь. Будь ласка, опублікуйте фактичну команду, яку ви виконуєте, повністю.
Мікель

2

Суть відповіді:

Використовуйте -s (захищайте аргументи) і додайте свій шлях у лапки:

rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"

Працює з обома пробілами або тире.


Дякую! Це правильне рішення, а не обхідне рішення.
m000

-2

Ви можете просто обговорити свій шлях цитатами.


1
Як ви, можливо, бачили в деталях питання, я справді це вже намагався. Однак інша відповідь запропонувала конкретне використання цитат, і це справді закінчилось. :)
purefusion

Вам потрібні КОЛИЧНІ котирування та зворотні риси.
Шрідхар Сарнобат
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.