Como posso definir variáveis de ambiente para um processo de rsync remoto?

12

Quando uso o rsync para copiar arquivos de um computador para outro, um processo de rsync é iniciado em ambas as extremidades. No entanto, no final remoto, os arquivos de inicialização do shell aparentemente não são lidos, portanto, não posso configurar variáveis de ambiente para o processo de rsync remoto. Infelizmente, há um servidor que eu preciso rsync para que rsync requer uma variável de ambiente para funcionar. Eu não sou um administrador no servidor, portanto não posso alterar a configuração global. O que posso fazer para definir variáveis de ambiente para um processo de rsync remoto?

    
por Ryan Thompson 04.11.2010 / 20:43

1 resposta

19

~/.profile normalmente não é lido quando você executa ssh somecommand , em oposição a uma sessão ssh interativa (ou outro método de login no qual você inicia uma sessão interativa).

O ssh suporta o envio de variáveis de ambiente. No OpenSSH, use a diretiva SendEnv em ~/.ssh/config . No entanto, a variável de ambiente específica deve ser ativada com uma diretiva AcceptEnv na configuração do servidor , então isso pode não funcionar para você.

O OpenSSH também permite definir variáveis de ambiente no lado do servidor. Novamente, isso deve ser ativado na configuração do servidor, aqui com a diretiva PermitUserEnvironment . As variáveis podem ser definidas no arquivo ~/.ssh/environment . Supondo que você use autenticação de chave pública, você também pode definir variáveis por chave em ~/.ssh/authorized_keys : adicione environment="FOO=bar" no início da linha relevante.

Uma coisa que acho que sempre funciona (por incrível que pareça) contanto que você esteja usando autenticação de chave pública é usar (ab) a opção command= no arquivo authorized_keys . Uma chave com uma opção command é boa apenas para executar o comando especificado; mas o comando no arquivo authorized_keys é executado com a variável de ambiente SSH_ORIGINAL_COMMAND definida para o comando especificado pelo usuário (vazio para sessões interativas). Então você pode usar algo assim em ~/.ssh/authorized_keys (claro, não será aplicável se você não usar essa chave para autenticar):

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

Note que coloquei as quebras de linha acima para legibilidade, mas isso realmente precisa estar em uma linha.

Outra possibilidade é escrever um script de wrapper ~/bin/rsync-wrapper no servidor, algo como

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

Em seguida, passe --rsync-path='bin/rsync-wrapper' na linha de comando rsync . O argumento para --rsync-path é expandido por um shell, portanto, se você preferir, pode tornar a linha de comando rsync auto-contida, passando algo como --rsync-path='. ~/.profile; rsync' .

Existe outra avenida que depende do seu shell de login ser bash ou zsh. Bash sempre lê ~/.bashrc quando é invocado por rshd ou sshd, mesmo que não seja interativo (mas não se for chamado como sh ). Zsh sempre lê ~/.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
    
por 04.11.2010 / 23:38