2

I can run a Python script on a remote machine like this:

ssh -t <machine> python <script>

And I can also set environment variables this way:

ssh -t <machine> "PYTHONPATH=/my/special/folder python <script>"

I now want to append to the remote PYTHONPATH and tried

ssh -t <machine> 'PYTHONPATH=$PYTHONPATH:/my/special/folder python <script>'

But that doesn't work because $PYTHONPATH won't get evaluated on the remote machine.

There is a quite similar question on SuperUser and the accepted answer wants me to create an environment file which get interpreted by ssh and another question which can be solved by creating and copying a script file which gets executed instead of python.

This is both awful and requires the target file system to be writable (which is not the case for me)!

Isn't there an elegant way to either pass environment variables via ssh or provide additional module paths to Python?

Community
  • 1
  • 1
frans
  • 6,905
  • 8
  • 40
  • 95
  • Is `PYTHONPATH` actually set on the remote machine, what does `ssh -t 'echo $PYTHONPATH'` say? – mata Nov 23 '16 at 08:31

2 Answers2

1

How about using /bin/sh -c '/usr/bin/env PYTHONPATH=$PYTHONPATH:/.../ python ...' as the remote command?

EDIT (re comments to prove this should do what it's supposed to given correct quoting):

bash-3.2$ export FOO=bar
bash-3.2$ /usr/bin/env FOO=$FOO:quux python -c 'import os;print(os.environ["FOO"])'
bar:quux
AKX
  • 93,995
  • 11
  • 81
  • 98
  • Seems to have no effect for me. `PYTHONPATH` has still the same value. When I run `/bin/sh -c '/usr/bin/env PYTHONPATH=$PYTHONPATH:/data/ echo $PYTHONPATH'` on my local machine, `PYTHONPATH` is printed unmodified – frans Nov 22 '16 at 17:16
  • That's because `$PYTHONPATH` there gets expanded before the env call by your shell. I'll augment my answer -- hold on. – AKX Nov 23 '16 at 08:19
1

WFM here like this:

$ ssh host 'grep ~/.bashrc -e TEST'
export TEST="foo"
$ ssh host 'python -c '\''import os; print os.environ["TEST"]'\'
foo
$ ssh host 'TEST="$TEST:bar" python -c '\''import os; print os.environ["TEST"]'\'
foo:bar

Note the:

  • single quotes around the entire command, to avoid expanding it locally
    • embedded single quotes are thus escaped in the signature '\'' pattern (another way is '"'"')
  • double quotes in assignment (only required if the value has whitespace, but it's good practice to not depend on that, especially if the value is outside your control)
  • avoiding of $VAR in command: if I typed e.g. echo "$TEST", it would be expanded by shell before replacing the variable

    • a convenient way around this is to make var replacement a separate command:

      $ ssh host 'export TEST="$TEST:bar"; echo "$TEST"'
      foo:bar
      
ivan_pozdeev
  • 28,628
  • 13
  • 85
  • 130