~/.profile
é executado apenas por shells de login. O programa que chama o shell decide se o shell será um shell de logon (colocando a -
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 apenas se você não especificar um comando. Portanto, se você especificar um comando, ~/.profile
não será lido.
O OpenSSH permite definir variáveis de ambiente no lado do servidor. Isso deve estar ativado na configuração do servidor , com a PermitUserEnvironment
diretiva. As variáveis podem ser definidas no arquivo ~/.ssh/environment
. Supondo que você use autenticação de chave pública, também é possível definir variáveis por chave em ~/.ssh/authorized_keys
: add 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 SendEnv
diretiva em ~/.ssh/config
. No entanto, a variável de ambiente específica deve ser ativada com uma AcceptEnv
diretiva na configuração do servidor; portanto, isso pode não funcionar para você.
Uma coisa que eu acho que sempre funciona (por incrível que pareça), desde que você esteja usando autenticação de chave pública é (ab) usar a command=
opção no authorized_keys
arquivo . Uma chave com uma command
opção é boa apenas para executar o comando especificado; mas o comando no authorized_keys
arquivo é executado com a variável de ambiente SSH_ORIGINAL_COMMAND
definida para o comando especificado pelo usuário. Essa variável está vazia se o usuário não especificou um comando e, portanto, esperava um shell interativo. Portanto, você pode usar algo parecido com isso ~/.ssh/authorized_keys
(é claro, isso não se aplicará 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, faça links simbólicos para esse script chamado rsync
, unison
etc. Passe --rsync-path='bin/rsync'
na rsync
linha de comando e assim por diante para outros programas. Como alternativa, alguns comandos permitem especificar um snippet de shell inteiro para executar remotamente, o que permite tornar o comando independente: por exemplo, com o rsync, você pode usar --rsync-path='. ~/.profile; rsync'
.
Existe outro caminho que depende do seu shell de login ser bash ou zsh. O Bash sempre lê ~/.bashrc
quando é chamado 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