Come chiamare. /home/test.sh in script Python

Sep 11 2020

Ho file chiamato . /home/test.sh(lo spazio tra il primo .ed /è intenzionale) che contiene alcune variabili ambientali. Devo caricare questo file ed eseguire il .py. Se eseguo il comando manualmente prima sul server Linux e poi eseguo lo script python, genera l'output richiesto. Tuttavia, voglio chiamare . /home/test.shda Python per caricare il profilo ed eseguire il resto del codice. Se questo profilo non viene caricato, gli script python vengono eseguiti e restituiscono 0 come output.

La chiamata

subprocess.call('. /home/test.sh',shell=True)

funziona bene ma il profilo non viene caricato sul terminale Linux per eseguire il codice python e fornire l'output desiderato.

Qualcuno può aiutare?

Risposte

2 alani Sep 12 2020 at 05:10

Le variabili d'ambiente non vengono ereditate direttamente dal processo genitore, motivo per cui il tuo approccio semplice non funziona.

Se stai cercando di raccogliere le variabili d'ambiente che sono state impostate nel tuo test.sh, allora una cosa che potresti fare invece è usarle envin una sub-shell per scriverle su stdout dopo aver acquisito lo script, e poi in Python puoi analizzarle e impostarli localmente.

Il codice seguente funzionerà a condizione che test.shnon scriva alcun output. (Se lo fa, allora quello che potresti fare per aggirarlo sarebbe echouna stringa di separazione dopo averlo acquisito, e prima di eseguire il env, e poi nel codice Python, rimuovere la stringa separatrice e tutto ciò che è prima di esso.)

import subprocess
import os

p = subprocess.Popen(". /home/test.sh; env -0", shell=True, 
                     stdout=subprocess.PIPE,
                     stderr=subprocess.PIPE)

out, _ = p.communicate()

for varspec in out.decode().split("\x00")[:-1]:
    pos = varspec.index("=")
    name = varspec[:pos]
    value = varspec[pos + 1:]
    os.environ[name] = value

# just to test whether it works - output of the following should include
# the variables that were set
os.system("env")

Vale anche la pena considerare che se tutto ciò che vuoi fare è impostare alcune variabili d'ambiente ogni volta prima di eseguire qualsiasi codice python, allora un'opzione è solo quella di estrarre il tuo test.shda un wrapper di script di shell e non provare a impostarli all'interno di python affatto:

#!/bin/sh
. /home/test.sh
exec "/path/to/your/python/script $@"

Quindi, quando vuoi eseguire il codice Python, esegui invece il wrapper.