~/.profile
é executado apenas por shells de login. O programa que chama o shell decide se o shell será um shell de login (colocando um -
como o primeiro caractere do argumento zeroth na invocação do shell). Normalmente não é executado quando você efetua login para executar um comando específico.
O OpenSSH, em particular, chama um shell de login somente se você não especificar um comando. Então, se você especificar um comando, ~/.profile
não será lido.
O OpenSSH permite definir variáveis de ambiente no lado do servidor. Isso deve ser ativado na configuração do servidor , com o PermitUserEnvironment
directiva. 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.
O ssh também 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, portanto, isso pode não funcionar para você.
Uma coisa que acho que sempre funciona (por incrível que pareça) contanto que você esteja usando a autenticação de chave pública é para (ab) usar 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. Esta variável está vazia se o usuário não especificou um comando e, portanto, esperava um shell interativo. 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=". ~/.profile; if [ -n \"$SSH_ORIGINAL_COMMAND\" ]; then eval \"$SSH_ORIGINAL_COMMAND\"; else exec \"$SHELL\"; fi" ssh-rsa …
Outra possibilidade é escrever scripts de wrapper no servidor. Algo como o seguinte em ~/bin/ssh-wrapper
:
#!/bin/sh
. ~/.profile
exec "${0##*/}" "$@"
Em seguida, crie links simbólicos para esse script chamado rsync
, unison
, etc. Passe --rsync-path='bin/rsync'
na linha de comando rsync
e assim por diante para outros programas. Como alternativa, alguns comandos permitem que você especifique um fragmento de shell inteiro para ser executado remotamente, o que permite que você torne o comando autônomo: por exemplo, com o rsync, você pode usar --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