¿Cómo puedo pasar una variable de entorno a través de un comando ssh? [duplicar]

43

¿Cómo puedo pasar un valor a un comando ssh, de modo que el entorno que se inicia en la máquina host comienza con una determinada variable de entorno establecida a mi elección?

EDITAR: El objetivo es pasar el escritorio kde actual (desde dcop kwin KWinInterface currentDesktop) al nuevo shell creado para que pueda devolver las ubicaciones nfs a mi instancia JEdit en el servidor original que es único para cada escritorio KDE. (Usando un mecanismo como emacsserver / emacsclient )

La razón por la que varias instancias ssh pueden estar en vuelo al mismo tiempo es porque cuando estoy configurando mi entorno, estoy abriendo un montón de instancias ssh diferentes a diferentes máquinas.

Ross Rogers
fuente

Respuestas:

19

El ~/.ssh/environmentarchivo se puede usar para establecer las variables que desea que estén disponibles para los comandos remotos. Tendrá que habilitar PermitUserEnvironmenten la configuración sshd.

Las variables establecidas de esta manera se exportan a procesos secundarios, por lo que puede:

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

y MyScript sabrá que Foo es Bar y Joe tiene 37 años.

John T
fuente
3
la variable necesita cambiar potencialmente cada llamada ssh
Ross Rogers
1
Podría ser mejor describir lo que estás tratando de hacer y por qué. Podría haber otras soluciones. El archivo de entorno debería generarse dinámicamente en cada llamada ssh, lo cual no es imposible.
EmmEff
¿Qué va a cambiar? ¿Los valores de esas variables o incluso sus nombres?
innaM
2
Esta respuesta realmente no parece responder la pregunta.
intuido
1
Esto se romperá si dos procesos intentan hacer esto con diferentes conjuntos de valores al mismo tiempo
nafg
55

La SendEnvopción es tu chico.

~ / .ssh / config: (localmente)

SendEnv MYVAR

/ etc / ssh / sshd_config: (en el extremo remoto)

AcceptEnv MYVAR

Ahora, cualquiera que sea el valor de $MYVARlocalmente, también estará disponible en la sesión remota.
Si inicia sesión varias veces, cada sesión tendrá su propia copia de $MYVAR, posiblemente con diferentes valores.

~/.ssh/environmentestá destinado a otros fines. Actúa como un $ENVarchivo cuando se ejecutan comandos que no son de shell de forma remota.


fuente
66
también se puede pasar (de manera más útil) a través de la línea de comando como ssh myserver -o SendEnv="MYVAR", para que pueda hacerlo dinámico en los scripts.
Mike Campbell
31

Puede pasar valores con un comando similar al siguiente:

ssh username@machine VAR=value cmd cmdargs

Puedes probar con:

ssh machine VAR=hello env

En tcsh, lo siguiente parece funcionar:

ssh machine "setenv VAR <value>; printenv"
Waltor
fuente
Parece que eso funciona bien para entornos bash. Lástima que estoy en un entorno corporativo tcsh.
Ross Rogers
2
¿Cómo puedo usar la sesión de forma interactiva?
luckydonald el
1
Tenga en cuenta que el primer ejemplo solo funciona para el primer comando si está encadenando comandos juntos (con &&). Usar bash, en export VAR=value;lugar de setenv en la tercera forma, funciona para este caso.
contrebis
2
¡Esto es lo que terminé haciendo! Donde quiera que vaya, lleve su entorno con usted. Su puede hacerlo así: ssh user@host "$(<env_to_source.sh) command ..." . En env a la fuente, tengo export var=value ; en líneas separadas (recuerde el punto y coma).
Tomasz Gandor
@TomaszGandor: años después, aún perfecto: me permite incluso pasar cosas complejas como PROMPT_COMMAND sin necesidad de preocuparme por escapar :-) 1000 gracias.
Pastilla roja
29

También hay un horrible, horrible truco.

Si su script está consumiendo la variable en el extremo remoto (es decir, puede nombrarla como desee), puede abusar de las variables locales. Cualquier variable de la forma LC_ * se pasará literalmente, sin necesidad de configuración alguna.

Por ejemplo, tenemos una serie de servidores de bastion en uno de mis clientes. Odio tener que conectarme a él, solo para conectarme a otro servidor ... y a otro servidor ... todo el tiempo. Tengo un script que se comporta como SSH, excepto que es inteligente.

Básicamente, si LC_BOUNCE_HOSTS está configurado, lo divide en espacios y despega el primer host. Luego rebota y ejecuta el mismo script. En el nodo de destino, esta lista finalmente está vacía, por lo que ejecuta el comando. También tengo un modo de depuración (que es excelente durante los problemas de red), establecido por LC_BOUNCE_DEBUG. Como ssh me pasa todo esto mágicamente, no tengo que hacer nada más que reconocer el final de la lista de hosts (lo que hago con una opción -).

Me siento sucio cada vez que uso esto, pero funciona en todas partes donde lo he probado.

Jayson
fuente
2
¿Por qué usarías algo así en lugar de la ProxyCommandopción integrada de OpenSSH ? Edite su ~/.ssh/configy agregue un bloque como Host *.example.com: ProxyCommand -ssh -W %h:%p bastionhosty deje que haga un túnel de sus conexiones por usted.
Kirk Strauser
1
Para túneles, no es tan malo. Para los entornos, hay dos razones: una, PermitUserEnvironment requiere acceso de administrador para configurar en el servidor para pasarlos directamente. Pasarlos a través de la línea de comando también es realmente difícil de lograr el escape correcto. Dos, se deben rebotar varios bastiones, lo que lo hace un poco más complejo, especialmente cuando no está claro desde el host de origen qué camino tomar hacia un determinado host de destino. Es más fácil decir: "bounce-ssh bast1 bast2 nodeX - rm -rf /" que mantener las rutas para una población de hosts en evolución en una serie de archivos ssh-config.
Jayson
Buena atrapada !! ¡Tan maravilloso y un poco sucio!
zw963
2
Esto es horrible Bravo. 👏
Pi Delport
1
Esto es terriblemente genial, ¡gracias! ¡Lo he usado para otro truco terriblemente agradable ! :)
lumbric
1
bla="MyEnvSelection=dcop"
ssh user@host "export $bla && ./runProg"

En bash probé con:

$ 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
fuente