Eu posso rodar um script localmente, mas não posso fazer “ssh HOSTNAME /path/to/script.sh”

3

Eu tenho um servidor linux e um desktop linux.

Eu escrevi o seguinte script simples para descarregar o banco de dados de um aplicativo da web do 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

O programa django-admin.py requer que a variável ambiental DJANGO_SETTINGS_MODULE funcione corretamente.

Se eu fizer ssh na máquina, ssh HOSTNAME e, em seguida, executar o script /var/www/example.com/dumper.sh do terminal bash no host remoto, tudo funcionará bem. Eu não recebo saída (como esperado), e o arquivo database.json está lá e tem os dados corretos.

No entanto (na minha área de trabalho linux), não consigo executar este comando: "ssh HOSTNAME /var/www/example.com/dumper.sh '' e recebo o seguinte erro:

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

É como se o comando export não estivesse sendo executado ou não estivesse sendo aplicado.

Por que isso não funciona? (Ou, alternativamente, deve funcionar? Estou enganado em pensar que isso deve funcionar?)

Atualização №1

Por sugestão do @faker, coloquei echo $PATH no script antes da chamada para django-admin.py . O . virtualenv/bin/activate altera o caminho do shell. Eu recebo um caminho de /var/www/example.com/virtualenv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11:/usr/games quando eu o executo via ssh HOSTNAME /path/to/script.sh , e depois de logar eu recebo /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 . A única diferença é a parte ~/bin , mas eu também fiz which django-admin.py , e em ambos os casos está usando /var/www/example.com/virtualenv/bin/django-admin.py , então em ambas as instâncias está usando o mesmo programa para o comando django-admin.py .

Atualização №2

No conselho de @Andrew Schulman sobre o mesmo, mas para $PYTHONPATH . PYTHONPATH estava vazio em ambos os casos. No entanto, adicionei python -c 'import sys; print sys.path' em vez de apenas echo $PYTHONPATH e obtive resultados diferentes.

Quando eu ssh em HOSTNAME e executo o script manualmente (aquele que funciona):

['', '/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']

Quando invoco o script por ssh (isso não funciona):

['', '/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']

A versão de trabalho tem um /var/www/example.com/mysite . O arquivo de configurações está localizado em /var/www/example.com/mysite/settings/my_hostname.py . Isso faz sentido, já que o invokcation de trabalho pode carregar o arquivo.

Por que a versão 'invocada remotamente' não está sendo usada em seu caminho de python?

    
por Rory 03.11.2011 / 23:24

3 respostas

2

Altere seu script e coloque -l após o shebang. então #!/bin/bash -l

Alternativamente, altere seu comando ssh para ssh HOSTNAME bash -l /var/www/example.com/dumper.sh

Fundamentação: Quando você executa ssh HOSTNAME command em vez de apenas ssh HOSTNAME , o shell usado para iniciar command não é um shell de 'login' e, portanto, diferentes scripts são chamados (Consulte a seção INVOCATION de man bash ) que resulta em seu ambiente sendo configurado de forma diferente.

    
por 04.11.2011 / 02:19
1

Eu descobri que você precisa citar a linha bash para reconhecer o -l corretamente, assim:

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

    
por 03.04.2014 / 21:27
1

Ao executar cmd sobre ssh em uma linha, o .profile não é lido. Para testar, tente isto:

ssh host env

Use isso para corrigir esse problema (as cotações são obrigatórias):

ssh host '. ~/.profile; cmd'

por exemplo:

ssh HOSTNAME '. ~/.bashrc; /var/www/example.com/dumper.sh'
    
por 19.02.2015 / 09:57