Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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?

share|improve this question
1  
You question needs to be a liiittle more specific. –  Ignacio Vazquez-Abrams Jul 13 '10 at 17:09
2  
The question was clear enough to me. However, from the ssh man page, I don't see any way to do that other than setting the variable manually once you've logged in to the server, unless you modify ~/.ssh2/environment. –  garyjohn Jul 13 '10 at 17:23
    
Is it a different variable each time? Or a different value? –  Dennis Williamson Jul 13 '10 at 17:52
    
Different value each time. –  Ross Rogers Jul 13 '10 at 20:37
add comment

4 Answers

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 (').

share|improve this answer
1  
Thanks much, I was in a rage that the stupid LC_* variables are exported on ssh and your answer directed me where to look. I just have to disable that in ~/.ssh/config –  akostadinov Oct 9 '12 at 16:37
    
I'm in the situation of the original poster, but the variable that I wanted forwarded is TERM, so I'm a bit puzzled by your answer. Has this automatic forwarding of TERM been disabled by recent OpenSSH versions? –  Doub Nov 20 '12 at 18:15
1  
@Doub The default is to refuse all environment variables on the server side, with AcceptEnv directives in sshd_config as desired by the administrator. But TERM is treated specially, as far as I know there is no way to filter it on the server side (it is set in the environment of the shell regardless of any configuration setting). Are you sure there isn't a profile script overriding it (like /etc/profile or ~/.profile or ~/.bashrc)? –  Gilles Nov 20 '12 at 18:24
    
@Gilles: I tested it again, and unless I explicitly add TERM to my AcceptEnv directive, the TERM is not passed on. I not opening a shell, but running a command directly, for example: "ssh -o SendEnv=TERM shell.example.com env". That prints all environment variable, and TERM only appears if it's in SendEnv on the client and AcceptEnv on the server. If I run "ssh -o SendEnv=TERM shell.example.com echo \${TERM}" withoug the AcceptEnv or SendEnv, it prints "dumb", which I'm not sure where it comes from (env doesn't even list TERM in that case). –  Doub Nov 27 '12 at 14:37
2  
@Doub Oh, I see. TERM is only transmitted if the client requests the server to allocate a tty. If there's no terminal on the remote side, it would be useless to transmit TERM. When you specify a command, if you want to have a terminal on the remote side, you need the -t command line option (or RequestTTY in ~/.ssh/config). –  Gilles Nov 27 '12 at 15:28
show 2 more comments

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
share|improve this answer
add comment

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

share|improve this answer
1  
It's very useful to know that this is set to "no" by default! –  jathanism Oct 4 '13 at 22:59
add comment

You could try invoking a custom command, assuming you have password-less ssh login setup. On the server, edit your ~/.ssh/authorized_keys entry that corresponds to the key from you client:

command="export VARIABLE=<something>" ssh-rsa <key>

Look at this link in the section Forced Command for a little more detail.

share|improve this answer
    
I tried this, but it doesn't work. It runs the command and exits, so there's no interactive session. Is that the normal behavior? If so, that could be useful if all you want to do is allow a specific key to trigger a specific command, but if you want to pass info that is used in a session (as the question states) then it is useless for that purpose. There IS no session. –  iconoclast Nov 7 '11 at 22:17
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.