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
環境変数が必要です。
マシンにSSHで接続し、ssh HOSTNAME
してから、リモートホストのbashターミナルからスクリプト/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
コマンドが実行されていないか、有効になっていないかのようです。
なぜこれが機能しないのですか? (または、代わりにshould動作しますか?これが動作するはずだと誤解していますか?)
@fakerの提案で、私はecho $PATH
を呼び出す前にスクリプトにDjango-admin.py
を入れました。 . virtualenv/bin/activate
はシェルパスを変更します。 /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
のパスを取得し、ログインした後、/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
に同じプログラムを使用しています。コマンド。
@Andrew Schulmanの同じアドバイスについてですが、$PYTHONPATH
についてです。どちらの場合も、PYTHONPATHは空でした。ただし、python -c 'import sys; print sys.path'
だけでなくecho $PYTHONPATH
を追加したところ、異なる結果が得られました。
HOSTNAMEに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/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
にあります。作業中の呼び出しでファイルをロードできるため、これは理にかなっています。
'リモートで呼び出された'バージョンがpythonパスでそれを取得しないのはなぜですか?
スクリプトを変更し、Shebangの後に-l
を置きます。だから#!/bin/bash -l
または、sshコマンドをssh HOSTNAME bash -l /var/www/example.com/dumper.sh
に変更します
理論的根拠:ssh HOSTNAME command
だけでなくssh HOSTNAME
を実行すると、command
の起動に使用されるシェルは「ログイン」シェルではないため、さまざまなスクリプトが呼び出されます(の「呼び出し」セクションを参照)。 man bash
)これにより、環境のセットアップが異なります。
次のように、-lを正しく認識するためにbash行を引用する必要があることを発見しました。
ssh HOSTNAME "bash -l /path/to/script.sh"
1行でsshに対してcmdを実行すると、.profileは読み取られません。テストするには、これを試してください:
ssh Host env
代わりにこれを使用してこの問題を修正してください(引用符は必須です):
ssh Host '. ~/.profile; cmd'
例えば:
ssh HOSTNAME '. ~/.bashrc; /var/www/example.com/dumper.sh'