Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have a linux server, and a linux desktop.

I have written the following simple script to dump the database of a django web application:

#! /bin/bash
set -o errexit

cd $(dirname $0)

. virtualenv/bin/activate

cd mysite

export DJANGO_SETTINGS_MODULE="settings.my_hostname"
django-admin.py dumpdata --settings=$DJANGO_SETTINGS_MODULE > database.json

The programme django-admin.py requires the DJANGO_SETTINGS_MODULE environmental variable to work properly.

If I ssh into the machine, ssh HOSTNAME, and then run the script /var/www/example.com/dumper.sh from the bash terminal on the remote host, and everything works fine. I get no output (as expected), and the file database.json is there and has the right data.

However (on my linux desktop), I cannot run this command: "ssh HOSTNAME /var/www/example.com/dumper.sh`` and I get the following error:

Traceback (most recent call last):
  File "/var/www/example.com/virtualenv/bin/django-admin.py", line 5, in <module>
    management.execute_from_command_line()
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/core/management/__init__.py", line 429, in execute_from_command_line
    utility.execute()
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/core/management/__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/core/management/__init__.py", line 261, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/core/management/__init__.py", line 67, in load_command_class
    module = import_module('%s.management.commands.%s' % (app_name, name))
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/core/management/commands/dumpdata.py", line 4, in <module>
    from django.db import connections, router, DEFAULT_DB_ALIAS
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/db/__init__.py", line 14, in <module>
    if not settings.DATABASES:
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/utils/functional.py", line 276, in __getattr__
    self._setup()
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/conf/__init__.py", line 42, in _setup
    self._wrapped = Settings(settings_module)
  File "/var/www/example.com/virtualenv/lib/python2.6/site-packages/django/conf/__init__.py", line 89, in __init__
    raise ImportError("Could not import settings '%s' (Is it on sys.path?): %s" % (self.SETTINGS_MODULE, e))
ImportError: Could not import settings 'settings.my_hostname' (Is it on sys.path?): No module named settings.my_hostname

It's as if the export command isn't being run, or isn't taking effect.

Why doesn't this work? (Or alternatively should it work? Am I mistaken in thinking that this should work?)

Update №1

On @faker's suggestion, I put echo $PATH in the script before the call to django-admin.py. The . virtualenv/bin/activate changes the shell path. I get a path of /var/www/example.com/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games when I run it via ssh HOSTNAME /path/to/script.sh, and after logging in I get /var/www/example.com/virtualenv/bin:/home/rory/bin/:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games. The only difference is the ~/bin part, but I did a which django-admin.py aswell, and in both instances it's using /var/www/example.com/virtualenv/bin/django-admin.py so in both instances it's using the same programme for the django-admin.py command.

Update №2

On @Andrew Schulman's advice of the same, but for $PYTHONPATH. PYTHONPATH was empty in both cases. However I added python -c 'import sys; print sys.path' instead of just echo $PYTHONPATH, and got different results.

When I ssh into HOSTNAME and run script manually (the one that works):

['', '/var/www/example.com/virtualenv/lib/python2.6/site-packages/distribute-0.6.10-py2.6.egg', '/var/www/example.com/virtualenv/lib/python2.6/site-packages/pip-1.0.2-py2.6.egg', '/var/www/example.com/mysite', '/home/rory/code/python/lib', '/var/www/example.com/virtualenv/lib/python2.6', '/var/www/example.com/virtualenv/lib/python2.6/plat-linux2', '/var/www/example.com/virtualenv/lib/python2.6/lib-tk', '/var/www/example.com/virtualenv/lib/python2.6/lib-old', '/var/www/example.com/virtualenv/lib/python2.6/lib-dynload', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/var/www/example.com/virtualenv/lib/python2.6/site-packages']

When I invoke the script over ssh (this doesn't work):

['', '/var/www/example.com/virtualenv/lib/python2.6/site-packages/distribute-0.6.10-py2.6.egg', '/var/www/example.com/virtualenv/lib/python2.6/site-packages/pip-1.0.2-py2.6.egg', '/var/www/example.com/virtualenv/lib/python2.6', '/var/www/example.com/virtualenv/lib/python2.6/plat-linux2', '/var/www/example.com/virtualenv/lib/python2.6/lib-tk', '/var/www/example.com/virtualenv/lib/python2.6/lib-old', '/var/www/example.com/virtualenv/lib/python2.6/lib-dynload', '/usr/lib/python2.6', '/usr/lib/python2.6/plat-linux2', '/usr/lib/python2.6/lib-tk', '/var/www/example.com/virtualenv/lib/python2.6/site-packages']

The working version has a /var/www/example.com/mysite. The settings file is located in /var/www/example.com/mysite/settings/my_hostname.py. This makes sense since the working invokcation can load the file.

Why isn't the 'remotely invoked' version getting that on it's python path?

share|improve this question
2  
Try ssh HOSTNAME "echo $PATH" and compare it with echo $PATH from a shell where running django-admin.py works. Is it different? –  faker Nov 3 '11 at 22:42
1  
Do the same as above with $PYTHONPATH. Note the message from Python on the last line: Could not import settings 'settings.my_hostname' (Is it on sys.path?) –  Andrew Schulman Nov 4 '11 at 10:26
add comment

2 Answers

Change your script and put -l after the shebang. so #!/bin/bash -l

Alternatively change your ssh command to ssh HOSTNAME bash -l /var/www/example.com/dumper.sh

Rationale: When you run ssh HOSTNAME command instead of just ssh HOSTNAME, the shell used to launch command is not a 'login' shell, and so different scripts get called (See the INVOCATION section of man bash) which results in your environment being setup differently.

share|improve this answer
    
Tried that, but it didn't work. I got the same output if I put a -l in the shebang line, or used ssh HOSTNAME -l … –  Rory Nov 4 '11 at 10:12
    
No, ssh HOSTNAME bash -l ..., you need to put the 'bash' there –  Patrick Nov 5 '11 at 4:31
    
I mistyped. I used ssh HOSTNAME bash -l /path/to/script.sh and it didn't work. –  Rory Nov 5 '11 at 16:54
add comment

I have discovered that you need to quote the bash line for it to recognize the -l properly, like this:

ssh HOSTNAME "bash -l /path/to/script.sh"

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