MODIFICA - Come risulta, questo è stato risolto in Fabric 1.4.4. Dal changelog:
[Caratteristica] #725: Aggiornamento locale di consentire di esclusione di cui guscio locale viene utilizzato. Grazie a Mustafa Khattab.
Quindi la domanda originale sarebbe stato riparato in questo modo:
def test():
local('c', shell='/bin/bash')
ho lasciato la mia risposta originale al di sotto, che riguarda solo la versione in tessuto < 1.4.4.
Perché locale non utilizza bash. Puoi vederlo chiaramente nell'output
/bin/sh: c: command not found
Vedere? Sta usando /bin/sh
invece di /bin/bash
. Questo perché il comando local
di Fabric si comporta in modo leggermente diverso internamente rispetto a run
. Il comando local
è essenzialmente un wrapper attorno alla classe python subprocess.Popen
.
http://docs.python.org/library/subprocess.html#popen-constuctor
E qui è il tuo problema. Il valore predefinito del Popen è /bin/sh
. È possibile specificare una shell diversa se si sta chiamando il costruttore di Popen da soli, ma lo si sta usando tramite Fabric. E sfortunatamente per te, Fabric non ti dà modo di passare una shell, come /bin/bash
.
Mi dispiace che non offra una soluzione, ma dovrebbe rispondere alla tua domanda.
EDIT
Ecco il codice in questione, tirato direttamente dal local
funzione di tessuto definita nel file operations.py
:
p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream,
stderr=err_stream)
(stdout, stderr) = p.communicate()
Come si può vedere, non passa in qualche cosa per la parola chiave eseguibile . Questo fa sì che usi l'impostazione predefinita, che è/bin/sh. Se fosse usato bash, sarebbe il seguente:
p = subprocess.Popen(cmd_arg, shell=True, stdout=out_stream,
stderr=err_stream, executable="/bin/bash")
(stdout, stderr) = p.communicate()
Ma non è così.Ecco perché nella documentazione per locale si dice quanto segue:
local è semplicemente un comodo wrapper attorno all'utilizzo del modulo di subprocesso Python integrato con shell = True attivato. Se devi fare qualcosa di speciale, considera l'utilizzo del modulo di sottoprocesso direttamente.
Ma il file [Fabric docs] (http://docs.fabfile.org/en/0.9.0/usage/env.html#shell) dice: "shell Predefinito: **/bin/bash ** -l -c Valore utilizzato come shell wrapper nell'esecuzione di comandi con ad esempio esecuzione. Deve essere in grado di esistere nel modulo "" - ad esempio il predefinito utilizza l'opzione -c di Bash che accetta una stringa di comando come valore." –
Sì, i documenti si riferiscono ai comandi run e sudo. Il comando locale funziona diversamente da quelli dietro le quinte. Ho modificato la risposta per mostrare il codice in questione. –
Grazie per il chiarimento. È stato molto istruttivo –