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.