Rsync wydaje się niezgodny z .bashrc (powoduje „czy twoja powłoka jest czysta?”)

16

Okazuje się, że rsync nie może współpracować ze zdalnym serwerem, który ma plik .bashrc?

Na kliencie lokalnym dostałem po uruchomieniu rsync:

protocol version mismatch -- is your shell clean?
(see the rsync man page for an explanation)
rsync error: protocol incompatibility (code 2) at compat.c(180) [sender=3.0.7]

Jak sugerowano tutaj, usunięcie pliku .bashrc na serwerze rozwiązało problem. Jak rozwiązać problem bez tymczasowego usuwania pliku .bashrc?

Computist
źródło
1
Sprawdź, czy ssh jest włączone dla tego konta.
Lamy,
Poniższe odpowiedzi są prawdopodobnie niepoprawne. Niedawno zacząłem otrzymywać ten błąd po rutynowej aktualizacji Ubuntu, mimo że nic nie zmieniło się w moich plikach .bashrc.
Cerin,
Nie - jeśli usunięcie pliku .bashrc rozwiązuje ten problem (jak stwierdzono w tym pytaniu), problem pojawia się w pliku .bashrc. Aktualizacja mogłaby z pewnością wprowadzić faktyczną niezgodność protokołu, co jest zupełnie inną kwestią.
Randall

Odpowiedzi:

21

Możesz napotkać problemy, jeśli .bashrcna zdalnym serwerze coś wyjdzie na terminal. Rsync może się tego nie spodziewać i może powodować problemy.

Możesz to naprawić, usuwając wszelkie polecenia z .bashrctekstu wyjściowego lub przesyłając dane wyjściowe do / dev / null.

Greg Hewgill
źródło
3
Więc jak potokować dane wyjściowe do / dev / null, jeśli mogę modyfikować pliki tylko na kliencie?
Computist
1
Przypuszczam, że możesz jako administrator systemu uzyskać pomoc. Możesz także być w stanie zmodyfikować pliki na serwerze w inny sposób, na przykład FTP lub scp.
Greg Hewgill
Tak, mój plik .bashrc zawierał echo „*** Uruchamianie powłoki ROOT ***” i echo „(Jeśli to możliwe, używaj sudo zamiast powłoki roota!)”. Usunięcie tych ech spowodowało problem.
Kentgrav,
1
Ze strony man rsync: „Niezgodność wersji protokołu - czy twoja powłoka jest czysta?” Ten komunikat jest zwykle spowodowany przez skrypty startowe lub narzędzie zdalnej powłoki wytwarzające niechciane śmieci w strumieniu używanym przez rsync do transportu. Aby zdiagnozować ten problem, uruchom zdalną powłokę w następujący sposób: ssh remotehost / bin / true> out.dat, a następnie spójrz na plik out.dat. Jeśli wszystko działa poprawnie, plik out.dat powinien być plikiem o zerowej długości.
Kentgrav,
8

Plik .bashrc nie jest naprawdę właściwym miejscem do generowania danych wyjściowych, ponieważ powoduje tego rodzaju problem. Jednak wiele osób ucieka, dopóki nie spróbują uruchomić rsync :-)

Wszelkie pożądane dane wyjściowe (i związane z nimi logiki i polecenia) należy przenieść do pliku .bash_profile (patrz np. Pytanie o awarię serwera „.profile vs. .bash_profile vs. .bashrc” w celu dalszej dyskusji na temat różnic między plikami).

W ten sposób nie będziesz musiał poświęcać uzyskiwania danych wyjściowych podczas logowania, ani zajmować się wprowadzaniem tymczasowych zmian w .bashrc, gdy chcesz użyć rsync.

Randall
źródło
6

Zawsze miałem pliki .bashrc na moich kontach użytkowników i nigdy nie miałem tego problemu, dopóki nie spróbowałem dziś zsynchronizować czegoś z moim serwerem przy użyciu konta root. Twój post pomógł mi znaleźć rozwiązanie:

Moje pliki $ user / .bashrc zawsze zaczynają się od poniższej sekcji, aby zapobiec tego rodzaju problemowi. Powieliłem go na .bashrc roota i rsync'ing działa teraz jak urok!

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

HTH, karsten

karsten
źródło
Zwykle to nie działa rsync, ponieważ jest z jakiegokolwiek powodu klasyfikowane jako „powłoka interaktywna”. Ale i tak warto to dodać, ponieważ w przeciwnym razie mogłoby to zepsuć nieinteraktywne powłoki.
Michael Schubert,
Myślę, że to najlepsze rozwiązanie tego pytania. Akceptuj odpowiedź „usuwanie wszelkich poleceń w pliku .bashrc wyświetlających tekst” nie jest praktyczne.
Qinsi
4

Ze złożonych powodów rsync / scp / sftp uruchamia .bashrc podczas łączenia się z innym hostem. Musisz mieć dowolne z tych poleceń u góry .bashrc :

zarówno

[[ $- != *i* ]] && return

lub

[ -z "$PS1" ] && return

Każde z powyższych poleceń pozwoli na wykonanie tylko pozostałych poleceń .bashrc dla sesji interaktywnych . O ile wiem, nie potrzebujesz ich do żadnej innej sesji (i rzeczywiście widziałem domyślny bashrc od Arch i Debiana używający tej techniki w swoim bashrc).

Jeśli jednak chcesz być wyjątkowo paranoikiem, jeśli chodzi o zezwolenie na uruchamianie poleceń bashrc nawet w przypadku sesji nieinteraktywnych, powinieneś przynajmniej zawinąć polecenia bashrc, które generują takie dane wyjściowe ( odniesienie ), aby działały tylko w sesjach interaktywnych:

if shopt -q login_shell; then
    # this is an interactive session, we _can_ display output
    ...code that produces output goes here...
fi

Zauważ, że inni sugerują przenoszenie poleceń, które wypisują tekst na twój profil bash, ale mam wątpliwości, czy to zawsze jest dobre (z powodów wyjaśnionych tutaj )

ndemou
źródło