3
2
I want to transfer an environment variable over SSH.
The "correct" way is using SendEnv/~/.ssh/environment
, but that requires the server to support AcceptEnv or PermitUserEnvironment, which it does not in my case.
So instead I am thinking to set the variable on the remote site like this:
FOO=val
export FOO
ssh server export FOO=$FOO'; do_stuff_which_uses_FOO'
That part is easy. I want a generic solution, so no matter the content of $FOO it will work. E.g.
FOO=" '\""
export FOO
QFOO=`quote "$FOO"` # quote will return "\ \ \'\\\""
export QFOO
ssh server export FOO=$QFOO'; do_stuff_which_uses_FOO'
This works no matter if the sending or receiving shell is sh or bash.
However, I also need it to work for csh/tcsh. And I will not know in advance which shell the receiving end is running. That means I have to code something that will work both in /bin/sh and /bin/csh.
So far I have managed to get it working for sh/bash:
ssh server // followed by the below quoted
eval `echo $SHELL | grep -E "/(t)?csh" > /dev/null && echo setenv FOO \\\ \\\ \\\\\'\\\\\" || echo export FOO=\\\ \\\ \\\\\'\\\\\";` ; echo "$FOO"
I can also get it to work for csh/tcsh (the user csh
has csh as login shell):
ssh csh@server // followed by the below quoted
eval `echo $SHELL | grep -E "/(t)?csh" > /dev/null && echo setenv FOO \\\ \\\ \\\\\'\\\\\" || echo export FOO=\\\ \\\ \\\\\'\\\\\";` ; echo "$FOO"
If $FOO is * or ? it works fine with BASH:
ssh server eval\ \`echo\ \$SHELL\ \|\ grep\ -E\ \"/\(t\)\?csh\"\ \>\ /dev/null\ \&\&\ echo\ setenv\ FOO\ \\\\\\\\\\\*\\\;\ \|\|\ echo\ export\ FOO=\\\\\\\\\\\*\\\;\`\;echo\ \"\$FOO\"\ a;
But it fails with csh:
ssh csh@server eval\ \`echo\ \$SHELL\ \|\ grep\ -E\ \"/\(t\)\?csh\"\ \>\ /dev/null\ \&\&\ echo\ setenv\ FOO\ \\\\\\\\\\\*\\\;\ \|\|\ echo\ export\ FOO=\\\\\\\\\\\*\\\;\`\;echo\ \"\$FOO\"\ a;
No match.
FOO: Undefined variable.
It seems * and ? refuse to be quoted with .
To answer this question your solution should:
- be able to transfer an environment variable to the remote server
- not use SendEnv/AcceptEnv/PermitUserEnvironment
- work no matter if the source shell is sh/bash/csh/tcsh
- work no matter if the destination shell is sh/bash/csh/tcsh
- work no matter the content of the environment variable. Specifically it should at least work for: \n * space ' " ? < > ! $ \ and any combination of those.
If you can find a better way to transfer the variable than quoting it, then that is fine, too.
It sounds like we're doing your homework. Why can you not use the ssh SendEnv or AcceptEnv options? That's what they are DESIGNED for. – UtahJarhead – 2012-10-15T13:50:32.863
It is to be used for --env in GNU Parallel. GNU Parallel is used by estimated 25000 users. A lot of these users do not have root access on the systems they are using (often it is compute clusters). If AcceptEnv had not required root access then I would agree. As you can see below I have found a solution that works for all but \n. – Ole Tange – 2012-10-15T17:57:18.597
Ah, that make sense. Thanks for the clarification. – UtahJarhead – 2012-10-15T18:01:44.067