J'ai un serveur linux et un ordinateur de bureau linux.
J'ai écrit le simple script suivant pour vider la base de données d'une application web django :
#! /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
Le programme django-admin.py
exige que le DJANGO_SETTINGS_MODULE
pour fonctionner correctement.
Si je me connecte à la machine, ssh HOSTNAME
puis exécutez le script. /var/www/example.com/dumper.sh
depuis le terminal bash de l'hôte distant, et tout fonctionne correctement. Je n'obtiens aucune sortie (comme prévu), et le fichier database.json
est là et possède les bonnes données.
Cependant (sur mon ordinateur de bureau linux), je ne peux pas exécuter cette commande : "ssh HOSTNAME /var/www/example.com/dumper.sh" et j'obtiens l'erreur suivante :
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
C'est comme si le export
n'est pas exécutée ou n'a pas d'effet.
Pourquoi cela ne fonctionne-t-il pas ? (Ou alternativement devrait cela fonctionne-t-il ? Est-ce que je me trompe en pensant que cela devrait fonctionner ?)
Mise à jour 1
Sur la suggestion de @faker, j'ai mis echo $PATH
dans le script avant l'appel à django-admin.py
. En . virtualenv/bin/activate
modifie le chemin d'accès à Shell. J'obtiens un chemin de /var/www/example.com/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games
lorsque je l'exécute via ssh HOSTNAME /path/to/script.sh
et après m'être connecté, j'obtiens /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
. La seule différence est le ~/bin
mais j'ai fait une which django-admin.py
également, et dans les deux cas, il utilise /var/www/example.com/virtualenv/bin/django-admin.py
Ainsi, dans les deux cas, il utilise le même programme pour la django-admin.py
commande.
Mise à jour 2
Sur le conseil de @Andrew Schulman, la même chose, mais pour $PYTHONPATH
. PYTHONPATH était vide dans les deux cas. Cependant, j'ai ajouté python -c 'import sys; print sys.path'
au lieu de echo $PYTHONPATH
et ont obtenu des résultats différents.
Lorsque je me connecte à HOSTNAME et que j'exécute script manuellement (celui qui fonctionne) :
['', '/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']
Lorsque j'invoque le script via ssh (cela ne fonctionne pas) :
['', '/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']
La version de travail comporte un /var/www/example.com/mysite
. Le fichier de configuration est situé dans /var/www/example.com/mysite/settings/my_hostname.py
. Cela est logique puisque l'invokcation de travail peut charger le fichier.
Pourquoi la version "invoquée à distance" ne l'obtient-elle pas sur son chemin Python ?