web-dev-qa-db-ja.com

スクリプトをローカルで実行できますが、「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環境変数が必要です。

マシンに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動作しますか?これが動作するはずだと誤解していますか?)

№1を更新

@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に同じプログラムを使用しています。コマンド。

№2を更新

@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パスでそれを取得しないのはなぜですか?

3
Rory

スクリプトを変更し、Shebangの後に-lを置きます。だから#!/bin/bash -l

または、sshコマンドをssh HOSTNAME bash -l /var/www/example.com/dumper.shに変更します

理論的根拠:ssh HOSTNAME commandだけでなくssh HOSTNAMEを実行すると、commandの起動に使用されるシェルは「ログイン」シェルではないため、さまざまなスクリプトが呼び出されます(の「呼び出し」セクションを参照)。 man bash)これにより、環境のセットアップが異なります。

2
Patrick

次のように、-lを正しく認識するためにbash行を引用する必要があることを発見しました。

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

1
Mike S

1行でsshに対してcmdを実行すると、.profileは読み取られません。テストするには、これを試してください:

ssh Host env

代わりにこれを使用してこの問題を修正してください(引用符は必須です):

ssh Host '. ~/.profile; cmd'

例えば:

ssh HOSTNAME '. ~/.bashrc; /var/www/example.com/dumper.sh'
1
sp1111