Jak ustawić zmienne środowiskowe dla zdalnego procesu rsync?

12

Kiedy używam rsync do kopiowania plików z jednego komputera na inny, proces rsync jest uruchamiany na obu końcach. Jednak na zdalnym końcu pliki inicjalizacji powłoki najwyraźniej nie są odczytywane, więc nie mogę skonfigurować zmiennych środowiskowych dla zdalnego procesu rsync. Niestety jest jeden serwer, który muszę rsync, na którym rsync wymaga zmiennej środowiskowej do działania. Nie jestem administratorem na serwerze, więc nie mogę zmienić konfiguracji globalnej. Co mogę zrobić, aby ustawić zmienne środowiskowe dla zdalnego procesu rsync?

Ryan C. Thompson
źródło
Jak rozpocząć proces rsync na serwerze? Czy możesz uruchomić skrypt przez ssh?
kraftan
Gdy to zrobisz rsync localfilename remotehost:remotefilename, proces rsync zostanie uruchomiony na serwerze. Nie jestem pewien, jak to zrobić, ale nie odczytuje żadnych plików inicjujących powłoki.
Ryan C. Thompson,

Odpowiedzi:

20

~/.profilezazwyczaj nie jest odczytywany podczas uruchamiania ssh somecommand, w przeciwieństwie do interaktywnej sesji ssh (lub innej metody logowania, w której rozpoczyna się sesję interaktywną).

Ssh obsługuje wysyłanie zmiennych środowiskowych. W OpenSSH użyj SendEnvdyrektywy w ~/.ssh/config. Jednak konkretna zmienna środowiskowa musi być włączona z AcceptEnvdyrektywą w konfiguracji serwera , więc może to nie zadziałać.

OpenSSH umożliwia także ustawianie zmiennych środowiskowych po stronie serwera. Ponownie należy to włączyć w konfiguracji serwera, tutaj z PermitUserEnvironmentdyrektywą. Zmienne można ustawić w pliku ~/.ssh/environment. Zakładając, że korzystasz z uwierzytelniania za pomocą klucza publicznego, możesz również ustawić zmienne dla poszczególnych kluczy w ~/.ssh/authorized_keys: dodaj environment="FOO=bar"na początku odpowiedniego wiersza.

Jedną rzeczą, która moim zdaniem zawsze działa (co dziwne), o ile korzystasz z uwierzytelniania za pomocą klucza publicznego, to (ab) użycie command=opcji z authorized_keyspliku. Klawisz z commandopcją nadaje się tylko do uruchomienia określonej komendy; ale polecenie w authorized_keyspliku działa ze zmienną środowiskową SSH_ORIGINAL_COMMANDustawioną na polecenie określone przez użytkownika (puste dla sesji interaktywnych). Możesz więc użyć czegoś takiego w ~/.ssh/authorized_keys(oczywiście nie będzie to miało zastosowania, jeśli nie użyjesz tego klucza do uwierzytelnienia):

command="export LD_LIBRARY_PATH=\"$HOME\"/lib;
         if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then
           eval \"$SSH_ORIGINAL_COMMAND\";
         else exec \"$SHELL\"; fi" ssh-rsa …

Zauważ, że wstawiłem powyżej podziału linii dla czytelności, ale tak naprawdę musi to być wszystko w jednym wierszu.

Inną możliwością jest napisanie skryptu opakowania ~/bin/rsync-wrapperna serwerze, coś w rodzaju

#!/bin/sh
. ~/.profile
exec rsync "$@"

Następnie przejść --rsync-path='bin/rsync-wrapper'na rsynclinii poleceń. Argument do --rsync-pathjest rozszerzany przez powłokę, więc jeśli wolisz, możesz ustawić linię poleceń rsync na własną rękę, przekazując coś podobnego --rsync-path='. ~/.profile; rsync'.

Istnieje inna droga, która zależy od tego, czy twoja powłoka logowania jest bash lub zsh. Bash zawsze czyta, ~/.bashrcgdy jest wywoływany przez rshd lub sshd, nawet jeśli nie jest interaktywny (ale nie, jeśli jest wywoływany jako sh). Zsh zawsze czyta ~/.zshenv.

## ~/.bashrc
if [[ $- != *i* ]]; then
  # Either .bashrc was sourced explicitly, or this is an rsh/ssh session.
  . ~/.profile
fi

## ~/.zshenv
if [[ $(ps -p $PPID -o comm=) = [rs]shd && $- != *l* ]]; then
  # Not a login shell, but this is an rsh/ssh session
  . ~/.profile
fi
Gilles „SO- przestań być zły”
źródło
Cóż, to właściwie podsumowuje. Miałem nadzieję, że jest lepszy sposób niż użycie skryptu opakowania.
Ryan C. Thompson
Ale chwileczkę. Jeśli moje pliki inicjujące powłoki nie są odczytywane, w jaki sposób może nawet znaleźć plik binarny rsync na serwerze? Zainstalowałem w ~ / usr, niestandardowej lokalizacji, którą muszę dodać do swoich $PATHskryptów inicjujących powłokę.
Ryan C. Thompson,
@ Ryan: Właściwie zapomniałem o najbardziej bezpośredniej metodzie (zobacz moją edycję), ale ona także wymaga dyrektywy, aby można było włączyć ją w konfiguracji serwera. Jeśli znalazłeś sposób, aby wziąć to PATHpod uwagę, powinieneś być w stanie ustawić tam dowolną inną zmienną. (Jeśli to nie zadziała, spróbuj dodać tyle śladów, ile możesz, zaczynając od set -xdowolnego skryptu powłoki; zamień rsyncplik binarny na skrypt, który zrzuca środowisko do pliku, a następnie wywołuje prawdziwy plik binarny.)
SO - przestańcie być źli '
Co ~/.ssh/rc?
Ryan C. Thompson,
@ Ryan: ~/.ssh/rcjest wykonywany przez osobny proces powłoki. Myślę, że najlepszym rozwiązaniem jest skrypt otoki lub --rsync-path='. ~/.profile; rsync'. Lub rekompilacja rsyncz odpowiednią ścieżką rpath zgodnie z drugim pytaniem.
Gilles 'SO - przestań być zły'