O SSH tem um recurso para transmitir variáveis de ambiente do cliente para o servidor, mas o OpenSSH o desativa na configuração do servidor padrão. Há uma exceção: TERM
, que tem um lugar especial no protocolo; mas comunicar informações via TERM
é complicado porque você precisa ter certeza de que o cliente irá decodificá-lo.
No entanto, alguns servidores são configurados para permitir a passagem de algumas variáveis de ambiente. Por exemplo, o Debian configura o servidor SSH para permitir todas as variáveis cujo nome comece com LC_
. Normalmente, essas são variáveis locais, mas você pode colocar o que quiser.
Se o servidor não estiver configurado para permitir qualquer variável, você poderá passá-las como parte do comando he, mas haverá algumas rugas. A ruga que você está atingindo é que, se você passar um comando para ssh
, por padrão, nenhum terminal será criado no servidor. Portanto, ssh [email protected] FOO=$FOO zsh
executa um shell, mas esse shell está conectado a um pipe, não a um terminal, portanto, ele não exibe uma edição de linha de comando de prompt ou de suporte. No entanto, você pode digitar comandos - tente digitar ls
Enter e exit
Inserir ou Ctrl + D para sair. A solução é informar explicitamente ao SSH para abrir um terminal, com a opção -t
.
ssh -t [email protected] FOO=$FOO zsh
Dependendo do seu shell de login, você pode querer executar
ssh -t [email protected] FOO=$FOO exec zsh
para evitar que um processo de shell extra seja o pai desse zsh
explicitamente invocado.
O segundo problema com o qual você não se deparou ainda é a citação. O protocolo SSH transmite uma string que é executada pelo shell remoto. Aqui, você está passando a string que consiste em FOO=
, seguida pelo valor de FOO
, seguido por um espaço e exec zsh
. Portanto, o valor de FOO
é interpretado como um pouco do código-fonte do shell, não como uma string para armazenar na variável FOO
. Isso faz diferença se o valor contiver caracteres que tenham um significado especial na sintaxe do shell. Você precisa adicionar um nível extra de cotação. Supondo que seu shell local seja zsh, você pode usar o sinalizador de expansão do parâmetro q
:
ssh -t [email protected] FOO=${(q)FOO} exec zsh
Outra diferença com o caso direto é que você está primeiro executando um shell de login no lado remoto e, em seguida, substituindo-o por um shell de não-login. Como a cadeia começa com um shell de login (isso não pode ser evitado), seu .profile
ou .zprofile
é executado; no entanto, a instância interativa de zsh não é um shell de login, o que pode fazer uma diferença dependendo do conteúdo de seus arquivos de ponto. A melhor solução para isso é provavelmente evitar fazer coisas frágeis em seus arquivos de ponto. Você pode executar zsh -l
, mas ele executa um segundo shell de login, que é propenso a fazer mais diferença (embora você possa consertar isso também, certificando-se de que seu .profile
ou .zprofile
seja idempotente). / p>