我有一个Linux服务器和一个Linux桌面。
我写了下面这个简单的脚本来转储一个django web应用程序的数据库:
#! /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
程序django-admin.py
要求DJANGO_SETTINGS_MODULE
环境variables正常工作。
如果我进入机器, ssh HOSTNAME
,然后从远程主机上的bashterminal运行脚本/var/www/example.com/dumper.sh
,一切工作正常。 我得到没有输出(如预期的),文件database.json
在那里,并有正确的数据。
但是(在我的Linux桌面上),我不能运行这个命令:“ssh HOSTNAME / var / www / example.com / dumper.sh“,我得到以下错误:
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
就好像export
命令没有运行,或者没有生效。
为什么这不工作? (或者,它应该工作吗?我错误地认为这应该起作用吗?)
在@ faker的build议中,我在调用django-admin.py
之前在脚本中放入了echo $PATH
。 的. virtualenv/bin/activate
. virtualenv/bin/activate
更改shellpath。 我得到/var/www/example.com/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games
的path/var/www/example.com/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games
当我通过ssh HOSTNAME /path/to/script.sh
运行ssh HOSTNAME /path/to/script.sh
,login后我得到/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
。 唯一的区别是~/bin
部分,但是我做了一个which django-admin.py
,并且在两个实例中都使用了/var/www/example.com/virtualenv/bin/django-admin.py
所以在这两种情况下它对django-admin.py
命令使用相同的程序。
对@安德鲁·舒尔曼的build议是一样的,但对于$PYTHONPATH
。 在这两种情况下,PYTHONPATH都是空的。 不过我加了python -c 'import sys; print sys.path'
python -c 'import sys; print sys.path'
而不是只是echo $PYTHONPATH
,并得到不同的结果。
当我SSH入HOSTNAME并手动运行脚本(工作的):
['', '/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']
当我通过SSH调用脚本(这不起作用):
['', '/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']
工作版本有一个/var/www/example.com/mysite
。 设置文件位于/var/www/example.com/mysite/settings/my_hostname.py
。 这是有道理的,因为工作调用可以加载文件。
为什么不是“远程调用”版本获取它的Pythonpath?
改变你的脚本,并在shebang后面加上-l
。 所以#!/bin/bash -l
或者,将您的ssh命令更改为ssh HOSTNAME bash -l /var/www/example.com/dumper.sh
理由:当您运行ssh HOSTNAME command
而不是ssh HOSTNAME
,用于启动command
的shell不是“login”shell,因此会调用不同的脚本(请参阅man bash
的INVOCATION部分),这会导致您的环境被设置不同。
我发现你需要引用bash行来正确识别-l,像这样:
ssh HOSTNAME“bash -l /path/to/script.sh”
当在一行中通过ssh运行cmd时,不会读取.profile文件。 为了testing,试试这个:
ssh host env
用这个来解决这个问题(引号是强制性的):
ssh host '. ~/.profile; cmd'
例如:
ssh HOSTNAME '. ~/.bashrc; /var/www/example.com/dumper.sh'