Come posso impostare le variabili di ambiente per un processo rsync remoto?


12

Quando utilizzo rsync per copiare file da un computer a un altro, viene avviato un processo rsync su entrambe le estremità. Tuttavia, sul lato remoto, i file di inizializzazione della shell apparentemente non vengono letti, quindi non posso impostare variabili di ambiente per il processo rsync remoto. Sfortunatamente, c'è un server che devo sincronizzare su cui rsync richiede una variabile d'ambiente per funzionare. Non sono un amministratore sul server, quindi non posso modificare la configurazione globale. Cosa posso fare per impostare le variabili d'ambiente per un processo rsync remoto?


Come si avvia il processo rsync sul server? Potresti attivare uno script tramite ssh?
Kraftan,

Quando lo fai rsync localfilename remotehost:remotefilename, un processo rsync viene avviato sul server. Non sono esattamente sicuro di come, ma non legge alcun file di inizializzazione della shell.
Ryan C. Thompson,

Risposte:


20

~/.profilein genere non viene letto durante l'esecuzione ssh somecommand, al contrario di una sessione ssh interattiva (o altro metodo di accesso in cui si avvia una sessione interattiva).

Ssh supporta l'invio di variabili d'ambiente. In OpenSSH, usa la SendEnvdirettiva in ~/.ssh/config. Tuttavia, la variabile di ambiente specifica deve essere abilitata con una AcceptEnvdirettiva nella configurazione del server , quindi potrebbe non funzionare per te.

OpenSSH consente inoltre di impostare variabili di ambiente sul lato server. Ancora una volta, questo deve essere abilitato nella configurazione del server, qui con la PermitUserEnvironmentdirettiva. Le variabili possono essere impostate nel file ~/.ssh/environment. Supponendo che tu utilizzi l'autenticazione con chiave pubblica, puoi anche impostare variabili per chiave in ~/.ssh/authorized_keys: aggiungi environment="FOO=bar"all'inizio della riga pertinente.

Una cosa che penso funzioni sempre (abbastanza stranamente) fintanto che stai usando l'autenticazione con chiave pubblica è (ab) usare l' command=opzione nel authorized_keysfile. Una chiave con commandun'opzione è valida solo per l'esecuzione del comando specificato; ma il comando nel authorized_keysfile viene eseguito con la variabile di ambiente SSH_ORIGINAL_COMMANDimpostata sul comando specificato dall'utente (vuoto per sessioni interattive). Quindi puoi usare qualcosa del genere in ~/.ssh/authorized_keys(ovviamente, non si applicherà se non usi questa chiave per autenticarti):

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

Nota che ho messo le interruzioni di riga sopra per leggibilità, ma questo in realtà deve essere tutto su una riga.

Un'altra possibilità è scrivere uno script wrapper ~/bin/rsync-wrappersul server, qualcosa del genere

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

Quindi passare --rsync-path='bin/rsync-wrapper'la rsyncriga di comando. L'argomento a --rsync-pathviene espanso da una shell, quindi se preferisci puoi rendere autonoma la riga di comando rsync passando qualcosa di simile --rsync-path='. ~/.profile; rsync'.

C'è un'altra strada che dipende dal fatto che la shell di accesso sia bash o zsh. Bash legge sempre ~/.bashrcquando viene invocato da rshd o sshd, anche se non è interattivo (ma non se si chiama come sh). Zsh legge sempre ~/.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

Bene, questo riassume praticamente tutto. Speravo ci fosse un modo migliore rispetto all'utilizzo di uno script wrapper.
Ryan C. Thompson,

Ma aspetta un minuto. Se i miei file di shell shell non vengono letti, come può persino trovare il binario rsync sul server? Ho installato in ~ / usr, un percorso non standard che devo aggiungere ai miei $PATHscript di shell init.
Ryan C. Thompson,

@Ryan: in realtà avevo dimenticato il metodo più diretto (vedi la mia modifica), ma richiede anche che una direttiva sia abilitata nella configurazione del server. Se hai trovato un modo per tenerne PATHconto, dovresti essere in grado di impostare qualsiasi altra variabile lì. (Se non funziona, prova ad aggiungere quante più tracce possibili, iniziando con set -xqualsiasi script di shell; sostituisci il rsyncbinario con uno script wrapper che scarica l'ambiente in un file e poi chiama il vero binario.)
SO di Gilles - smetti di essere malvagio '

Che dire ~/.ssh/rc?
Ryan C. Thompson,

@Ryan: ~/.ssh/rcviene eseguito da un processo di shell separato. Penso che la tua scommessa migliore sia uno script wrapper o --rsync-path='. ~/.profile; rsync'. O ricompilare rsynccon un percorso adeguato secondo l'altra domanda.
Gilles 'SO- smetti di essere malvagio'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.