Kiedy używasz SSH do łączenia rsync ze zdalnym serwerem, w jaki sposób unikasz spacji i tym podobnych na zdalnej ścieżce? Prosty ukośnik odwraca miejsce dla znaku zachęty lokalnego bash, ale na zdalnej maszynie przestrzeń jest następnie odczytywana jako przerwa na ścieżce, oznaczając w ten sposób koniec tej ścieżki.
Kiedy więc to robię rsync -avz /path/to/source/some\ dir/ [email protected]:/path/to/dest/some\ dir/
, zdalny serwer odczytuje to jako słuszne /path/to/dest/some/
i ponieważ nie może zdalnie znaleźć tego miejsca docelowego, ponieważ rzeczywistym miejscem docelowym jest „niektóre katalog”, a nie tylko „niektóre”.
Jeśli spróbuję wykonać to samo polecenie i uciec od ukośnika odwrotnego i miejsca, aby ominąć lokalny monit bash i zachować odwrotny ukośnik dla zdalnego serwera (łącznie trzy ukośniki odwrotne:) /path/to/dest/some\\\ dir/
, to rzeczywiście wysyła odwrotny ukośnik do zdalnego serwera, ale zdalny serwer następnie interpretuje ścieżkę /path/to/dest/some\/
raczej niż /path/to/dest/some\ dir/
rozbija spację i znaki po niej.
Jeśli spróbuję zawinąć ścieżkę w cudzysłów, zachowuje się ona w ten sam sposób, skutecznie odcinając ścieżkę w przestrzeni. Więc to działa tylko, aby ominąć lokalny monit bash.
Początkowo korzystałem ze ścieżki, w której znajdował się segment „-” (spacja-myślnik-spacja), a serwer zdalny zwrócił błąd, rsync: on remote machine: -: unknown option
który w pierwszej kolejności zapoczątkował tę ucieczkę w przestrzeń.
Co więc muszę zrobić, aby działało to poprawnie ze zdalnym serwerem, bez konieczności usuwania spacji lub innych błędnych znaków, takich jak łączniki ze zdalnej ścieżki?
-s
rozwiązuje problem bez konieczności zastosowania podwójnej ucieczki ręcznie.Odpowiedzi:
Na maszynie inicjującej
rsync
buduje wiersz poleceń, który wywołuje cel rsync na komputerze zdalnym, a następnie wysyła ten wiersz poleceń za pomocą ssh .... jako pojedynczego ciągu . Ten pojedynczy ciąg jest przekazywany do powłoki w celu przeanalizowania, podzielenia na argumenty i wykonaniarsync
. Nie mam pojęcia, dlaczego tak się dzieje, zamiast pakować (już podzielone, rozwinięte i niecytowane) argumenty w jakiś bezpieczny kontener binarny do zdalnego rsync.Oznacza to, że argumenty będą przetwarzane przez dwóch różnych muszli, cytat i rekwotowaniu odpowiednio. Zazwyczaj każdy argument owijam podwójnymi cudzysłowami, a następnie całe wyrażenie na pojedyncze cudzysłowy. czasem to nie wystarczy lub może być skomplikowane, jeśli chcesz, aby to samo wyrażenie było używane lokalnie i zdalnie.
W takich przypadkach zwykle ustawiam niektóre miękkie linki z prostymi nazwami bez spacji i wyłącznie ASCII i używam ich.
źródło
'[email protected]:"/path/to/dest/some\ dir/"'
eval
lub może poprzez wywołanie funkcji?Byłeś na dobrej drodze, kiedy powiedziałeś:
Oto sposób, w jaki najłatwiej to zrobić:
i tak też działa.
Czy możesz opublikować dokładne dane wyjściowe i jakiekolwiek błędy, które widzisz?
Czy możesz zastąpić
rsync
po obu stronach skryptem opakowania?Następnie uruchom ponownie rsync i powinno to udowodnić, że ten sposób ucieczki działa, np
Strona klienta:
Po stronie serwera:
W powyższym przykładzie fakt, że czwarty argument na serwerze (
dir with spaces
) znajduje się w jednym wierszu, oznacza, że cytowanie działa poprawnie.Jeśli to nie pomoże, spróbuj ponownie uruchomić
rsync -v
, lubrsync -vv
, lubrsync -vvv
. Dostarczy dodatkowych informacji debugowania.Dwie inne głupie sugestie:
-a
lub-r
?źródło
Odpowiedź na pytanie:
Użyj -s (chroń argumenty) i umieść swoją ścieżkę w cudzysłowie:
rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"
Działa zarówno z odstępami, jak i myślnikami.
źródło
Możesz po prostu zawrzeć swoją ścieżkę w cudzysłowie.
źródło