2011-11-29 10 views
39

Vorrei passare alcuni valori da fabric nell'ambiente remoto e non vedo un ottimo modo per farlo. Il migliore che è venuta in mente finora è:Il modo migliore per aggiungere una variabile di ambiente in tessuto?

with prefix('export FOO=BAR'): 
    run('env | grep BAR') 

Questo non sembra funzionare, ma sembra un po 'di hack.

Ho cercato nel repository GIT e sembra che questo sia issue #263.

+1

Ma le variabili permangono dopo che il tessuto ha chiuso la connessione? Dalla documentazione ('prefix' e' shell_env') capisco che le variabili di ambiente saranno impostate solo per i comandi avvolti. – glarrain

risposta

11

Penso che la soluzione basata su prefix sia perfettamente valida. Tuttavia, se si vuole avere un manager shell_env contesto come quello proposto in issue#263, è possibile utilizzare il seguente implementazione alternativa nei file fab:

from fabric.api import run, env, prefix 
from contextlib import contextmanager 

@contextmanager 
def shell_env(**env_vars): 
    orig_shell = env['shell'] 
    env_vars_str = ' '.join('{0}={1}'.format(key, value) 
          for key, value in env_vars.items()) 
    env['shell']='{0} {1}'.format(env_vars_str, orig_shell) 
    yield 
    env['shell']= orig_shell 

def my_task(): 
    with prefix('echo FOO1=$FOO1, FOO2=$FOO2, FOO3=$FOO3'): 
     with shell_env(FOO1='BAR1', FOO2='BAR2', FOO3='BAR3'): 
      run('env | grep BAR') 

Si noti che questo manager contesto modifica env['shell'] invece di env['command_prefixes'] (come prefix contesto direttore fa), in modo da:

  • è ancora possibile utilizzare prefix (vedi esempio sotto uscita) senza i problemi di interazione di cui issue#263.
  • è necessario applicare qualsiasi modifica a env['shell'] prima di utilizzare shell_env. Altrimenti, le modifiche shell_env verranno sovrascritte e le variabili di ambiente non saranno disponibili per i comandi.

Quando si esegue il file fab sopra, si ottiene il seguente output:

$ fab -H localhost my_task 
[localhost] Executing task 'my_task' 
[localhost] run: env | grep BAR 
[localhost] out: FOO1=BAR1, FOO2=BAR2, FOO3=BAR3 
[localhost] out: FOO1=BAR1 
[localhost] out: FOO2=BAR2 
[localhost] out: FOO3=BAR3 
[localhost] out: 

Done. 
Disconnecting from localhost... done. 
+1

Ho usato questa tecnica, ma ho notato che nelle versioni successive del tessuto non funziona più. Invece, dovresti/devi usare l'implementazione fabric.context_managers.shell_env, che funziona. –

2

Tessuto 1.5.0 (attualmente in Git) batte shell come locale() argomento di nome. Se si passa '/ bin/bash' lì, lo passa all'argomento eseguibile di Popen.

Non eseguirà il tuo .bashrc anche se .bashrc è originato dall'invocazione interattiva di bash. È possibile fonte di ogni file che si desidera all'interno locale:

local('. /usr/local/bin/virtualenvwrapper.sh && workon focus_tests && bunch local output', shell='/bin/bash') 
56

Come di tessuto 1.5 (rilasciato), fabric.context_managers.shell_env fa ciò che si vuole.

with shell_env(FOO1='BAR1', FOO2='BAR2', FOO3='BAR3'): 
     local("echo FOO1 is $FOO1") 
+1

Non sembra funzionare su Windows. È stato aggiunto il supporto, ma non è nell'ultima versione (1.6). –

+0

Ma le variabili permangono dopo che il tessuto ha chiuso la connessione? Dalla documentazione capisco che le variabili di ambiente saranno impostate solo per i comandi avvolti. – glarrain

+0

@glarrain sì, questo è il punto che li implementano come un gestore di contesto – Anentropic

Problemi correlati