Como posso passar uma variável de ambiente através de um comando ssh? [duplicado]

43

Como posso passar um valor para um comando ssh, de modo que o ambiente iniciado na máquina host inicie com uma determinada variável de ambiente definida para a minha escolha?

EDIT: O objetivo é passar a área de trabalho atual do kde (do dcop kwin KWinInterface currentDesktop) para o novo shell criado, para que eu possa retornar os locais nfs para a minha instância do JEdit no servidor original, exclusivo para cada área de trabalho do KDE. (Usando um mecanismo como emacsserver / emacsclient )

A razão pela qual várias instâncias ssh podem estar em andamento ao mesmo tempo é porque, quando estou configurando meu ambiente, estou abrindo várias instâncias ssh diferentes para máquinas diferentes.

Ross Rogers
fonte

Respostas:

18

O ~/.ssh/environmentarquivo pode ser usado para definir variáveis ​​que você deseja disponibilizar para comandos remotos. Você precisará habilitar PermitUserEnvironmentna configuração sshd.

As variáveis ​​definidas dessa maneira são exportadas para processos filho, para que você possa:

echo "Foo=Bar" > sshenv
echo "Joe=37" >> sshenv
scp sshenv user@server:~/.ssh/environment
ssh user@server myscript

e o myscript saberá que Foo é Bar e Joe tem 37 anos.

John T
fonte
3
a variável precisa mudar potencialmente cada chamada ssh
Ross Rogers
11
Pode ser melhor descrever o que você está tentando fazer e por quê. Pode haver outras soluções. O arquivo do ambiente precisaria ser gerado dinamicamente em cada chamada ssh, o que não é impossível.
EmmEff
O que vai mudar? Os valores dessas variáveis ​​ou mesmo seus nomes?
InnaM 30/09/09
2
Essa resposta realmente não parece responder à pergunta.
intuído
11
Isso será interrompido se dois processos estiverem tentando fazer isso com diferentes conjuntos de valores simultaneamente
nafg 28/03
55

A SendEnvopção é sua cara.

~ / .ssh / config: (localmente)

SendEnv MYVAR

/ etc / ssh / sshd_config: (na extremidade remota)

AcceptEnv MYVAR

Agora, qualquer que seja o valor $MYVARlocal, ele também estará disponível na sessão remota.
Se você efetuar login várias vezes, cada sessão terá sua própria cópia $MYVAR, com valores possivelmente diferentes.

~/.ssh/environmentdestina-se a outros fins. Ele funciona como um $ENVarquivo ao executar comandos que não são de shell remotamente.


fonte
6
também pode ser passado (com mais utilidade) pela linha de comando como ssh myserver -o SendEnv="MYVAR", para que você possa torná-lo dinâmico em scripts.
Mike Campbell
31

Você pode passar valores com um comando semelhante ao seguinte:

ssh username@machine VAR=value cmd cmdargs

Você pode testar com:

ssh machine VAR=hello env

No tcsh, o seguinte parece funcionar:

ssh machine "setenv VAR <value>; printenv"
Waltor
fonte
Parece que isso funciona bem para ambientes bash. Pena que estou em um ambiente tcsh corporativo.
Ross Rogers
2
Como posso usar a sessão interativamente?
luckydonald
11
Observe que o primeiro exemplo só funciona para o primeiro comando se você estiver encadeando comandos juntos (com &&). Usando bash, em export VAR=value;vez de setenv na terceira forma, funciona para este caso.
contrebis 28/02
2
Foi isso que acabei fazendo! Onde quer que você vá, leve seu ambiente com você. Sua pode fazê-lo assim: ssh user@host "$(<env_to_source.sh) command ..." . Em env para fonte, eu tenho export var=value ; em linhas separadas (lembre-se do ponto e vírgula).
Tomasz Gandor 11/01
@ TomaszGandor: anos depois, ainda perfeito - me permite passar coisas complexas como PROMPT_COMMAND lá em cima, sem precisar me preocupar em escapar :-) 1000 obrigado.
Red Pill
29

Há também um truque horrível.

Se o seu script estiver consumindo a variável na extremidade remota (ou seja, você pode nomeá-la como quiser), poderá abusar das variáveis ​​de localidade. Qualquer variável do formato LC_ * será transmitida literalmente, sem nenhum requisito de configuração.

Por exemplo, temos uma série de servidores bastiões em um dos meus clientes. Eu odeio ter que me conectar a ele, apenas para me conectar a outro servidor ... e outro servidor ... sempre. Eu tenho um script que se comporta exatamente como SSH, exceto que é inteligente.

Basicamente, se LC_BOUNCE_HOSTS estiver definido, ele o dividirá em espaços e removerá o primeiro host. Em seguida, ele salta e executa o mesmo script. No nó de destino, essa lista está eventualmente vazia e, portanto, executa o comando. Também tenho um modo de depuração (ótimo durante problemas de rede), definido por LC_BOUNCE_DEBUG. Como o ssh transmite tudo isso para mim magicamente, não preciso fazer nada além de reconhecer o final da lista de hosts (o que faço com a opção -).

Eu me sinto sujo toda vez que uso isso, mas funciona em todos os lugares em que tentei.

Jayson
fonte
2
Por que você usaria algo assim em vez da opção interna do OpenSSH ProxyCommand? Edite seu ~/.ssh/confige adicione um bloco como Host *.example.com: ProxyCommand -ssh -W %h:%p bastionhoste permita que ele tunele suas conexões para você.
precisa saber é o seguinte
11
Para túneis, não é tão ruim. Para envs, dois motivos: Um, PermitUserEnvironment requer acesso de administrador para configurar no servidor para transmiti-los diretamente. Passá-los pela linha de comando também é realmente difícil de conseguir a fuga certa. Segundo, vários bastiões devem ser devolvidos, tornando isso um pouco mais complexo - especialmente quando não está claro no host de origem qual caminho seguir para um determinado host de destino. É mais fácil dizer: "bounce-ssh bast1 bast2 nodeX - rm -rf /" do que manter as rotas para uma população em evolução de hosts em uma série de arquivos ssh-config.
21712 Jayson
Boa pegada !! Tão maravilhoso e um pouco sujo !!
Zw963
2
Isto é horrível. Bravo. Del
Pi Delport
11
Isso é horrivelmente ótimo, obrigado! Eu o usei para mais um truque terrivelmente agradável ! :)
lumbric
1
bla="MyEnvSelection=dcop"
ssh user@host "export $bla && ./runProg"

No bash eu testei com:

$ echo '#!/bin/sh' > readEnv.sh
$ echo 'echo "MyEnv: "$MyEnvFromSSH' >> readEnv.sh

$ scp readEnv.sh user@host:~/
$ bla="MyEnvFromSSH=qwert"
$ ssh user@host "export $bla && ./readEnv.sh"
Zeh
fonte