When ssh'ing, how can I set an environment variable on the server that changes from session to session?
When I ssh
into a server, how can I pass an environment variable from the client to the server? This environment variable changes between different invocations of ssh so I don't want to overwrite $HOME/.ssh2/environment
every time I do an ssh call. How can I do this?
Of course, you can set the environment variable inside the command, however you'll have to be careful about quoting: remember that your shell is going to parse your local command line, and then the remote shell will have a go on the string it receives.
If you want a variable to get the same value on the server that it has on the client, try the SendEnv
option:
ssh -o SendEnv=MYVAR server.example.com mycommand
This requires support from the server, though. With OpenSSH, the variable name has to be authorized in /etc/sshd_config
.
If the server only allows certain specific variable names, you can work around that; for example a common setup allows LC_*
through, and you can do the following:
ssh -o SendEnv=LC_MYVAR server.example.com 'MYVAR=$LC_MYVAR; unset LC_MYVAR; export MYVAR; mycommand'
If even LC_*
is not an option, you can pass information in the TERM
environment variable, which is always copied (there may be a length limit however). You'll still have to make sure that the remote shell doesn't restrict the TERM
variable to designate a known terminal type. Pass the -t
option to ssh if you're not starting a remote interactive shell.
env TERM="extra information:$TERM" ssh -t server.example.com 'MYVAR=${TERM%:*}; TERM=${TERM##*:}; export MYVAR; mycommand'
Another possibility is to define the variable directly in the command:
ssh -t server.example.com 'export MYVAR="extra information"; mycommand'
Thus, if passing a local variable:
ssh -t server.example.com 'export MYVAR='"'$LOCALVAR'"'; mycommand'
However, beware of quoting issues: the value of the variable will be interpolated directly into the shell snippet executed on the remote side. The last example above assumes that $LOCALVAR
does not contain any single quotes ('
).
If you can administrate the target host you can configure sshd to allow passing your local environment variables along to the target host.
From the sshd_config man page:
PermitUserEnvironment
Specifies whether ~/.ssh/environment and environment= options in
~/.ssh/authorized_keys are processed by sshd. The default is
"no". Enabling environment processing may enable users to bypass
access restrictions in some configurations using mechanisms such
as LD_PRELOAD.
sshd configuration typically lives at /etc/ssh/sshd_config
On your local client, in your ~/.ssh/config
you can add SetEnv
, e.g.
Host myhost
SetEnv FOO=bar
Note: Check man ssh_config
.
Then on the server, make sure to allow client to pass certain environment variables in your /etc/ssh/sshd_config
config file:
AcceptEnv LANG LC_* FOO BAR*
Note: Check man sshd_config
.
So, on your client, you have some environment variable, and you want that to be available to the remote command? I don't think there's a way to have ssh magically pass it along, but you can probably do something like this. Instead of using, say:
ssh remote.host my_command
You can do this:
ssh remote.host env ENV_VAR=$ENV_VAR my_command
@emptyset's response (which didn't work for me) led me to this answer:
You can add this command to your ~/.ssh/authorized_keys
file:
command="/usr/bin/env VARIABLE=<something> $SHELL" ssh-rsa <key>
export VARIABLE=<something>
was immediately exiting, and the SSH connection was closed (locking me out of the server), whereas /usr/bin/env ... $SHELL
will run your default shell with a modified environment.