我可以在本地运行脚本,但不能做“ssh HOSTNAME /path/to/script.sh”

我有一个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命令没有运行,或者没有生效。

为什么这不工作? (或者,它应该工作吗?我错误地认为这应该起作用吗?)

更新№1

在@ 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命令使用相同的程序。

更新№2

对@安德鲁·舒尔曼的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'