How can I pass an environment variable through an ssh command? [duplicate]
The ~/.ssh/environment
file can be used to set variables you want available for remote commands. You will have to enable PermitUserEnvironment
in the sshd configuration.
Variables set this way are exported to child processes, so you can:
echo "Foo=Bar" > sshenv
echo "Joe=37" >> sshenv
scp sshenv user@server:~/.ssh/environment
ssh user@server myscript
and myscript will know that Foo is Bar and Joe is 37.
The SendEnv
option is your guy.
~/.ssh/config: (locally)
SendEnv MYVAR
/etc/ssh/sshd_config: (on the remote end)
AcceptEnv MYVAR
Now, whatever the value of $MYVAR
locally is, it becomes available in the remote session too.
If you login multiple times, each session will have its own copy of $MYVAR
, with possibly different values.
~/.ssh/environment
is meant for other purposes. It kind of acts as $ENV
file when executing non-shell commands remotely.
You can pass values with a command similar to the following:
ssh username@machine VAR=value cmd cmdargs
You can test with:
ssh machine VAR=hello env
On tcsh the following seems to work:
ssh machine "setenv VAR <value>; printenv"
There's also a horrible, horrible hack.
If your script is consuming the variable on the remote end (i.e. you can name it whatever you want), you can abuse the locale variables. Any variable of the form LC_* will be passed on verbatim, with no requirement for configuration whatsoever.
For example, we have a series of bastion servers at one of my clients. I hate having to connect to it, just to connect to another server... and another server... every time. I have a script that behaves just like SSH, except that it's clever.
Basically, if LC_BOUNCE_HOSTS is set, it splits it on spaces and peels off the first host. Then it bounces through and runs the same script. On the destination node, this list is eventually empty, so it runs the command. I also have a debug mode (which is great during network troubles), which is set by LC_BOUNCE_DEBUG. Since ssh passes all of these along for me magically, I don't have to do anything other than recognize the end of the host list (which I do with a -- option).
I feel dirty every time I use this, but it works everywhere I've tried it.