bonjour,
Par avance désolé pour la longueur de cette question, mais je tourne en rond sur ce problème depuis 3 semaines. J'ai essayé de faire un exemple simple.
Je suis sous linux et je suis dépendant d'un environement de dev que je set via des bash fournis par une infra.
Pour la suite, considérons que le fichier tar joint est décompressé dans /tmp (tar -C /tmp/ -xvf env.tar.gz)
env.tar.gz
je veux scripter via python la séquence suivante
~$ . /tmp/tools/setEnv
~$ activateEnv v1
~$ rootCmd.sh
runing rootCmd : /tmp/tools/envs/cmds/common/rootCmd.sh
calling subCmd : /tmp/tools/envs/cmds/v1/convert-1.0.3.sh -u http://www.operation.com/api/
convert : trying reaching http://www.operation.com/api/
~$ activateEnv v2
~$ rootCmd.sh
runing rootCmd : /tmp/tools/envs/cmds/common/rootCmd.sh
calling subCmd : /tmp/tools/envs/cmds/v2/inspect-1.4.2.sh -u http://www.audit.com/api/
inspect : trying reaching http://www.audit.com/api/
mon soucis, c'est que setEnv definis des fonctions shell (ici activateEnv), et positionne des variables.
Pour les variables j'ai pu régler le problème en passant par une fonction python qui après chaque call de commande récupère les variables et vient les setter dans l'environement python.
cf /tmp/python/utils.py
si je scripte la séquence initiale, j'obtiens une erreur car la fonction shell activateEnv n'est pas trouvée
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 def call_cmd(cmd): with tempfile.NamedTemporaryFile() as f: call = cmd + ' && env>' + f.name out = (subprocess.Popen(call, shell=True, stdout=subprocess.PIPE).stdout.read().decode('utf-8')) for e in f.read().splitlines(): e = e.decode('utf-8').strip().split('=') os.environ[e[0]] = e[1] return out
~$ python3 /tmp/python/script_KO.py
***** ENV V1 *****
/bin/sh: activateEnv: command not found
/tmp/tools/envs/cmds/common/rootCmd.sh: line 4: /-.sh: No such file or directory
runing rootCmd : /tmp/tools/envs/cmds/common/rootCmd.sh
calling subCmd : /-.sh -u
***** ENV V2 *****
/bin/sh: activateEnv: command not found
/tmp/tools/envs/cmds/common/rootCmd.sh: line 4: /-.sh: No such file or directory
runing rootCmd : /tmp/tools/envs/cmds/common/rootCmd.sh
calling subCmd : /-.sh -u
pour que ça fonctionne, il faut que j'appelle setEnv avant chaque activateEnv
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 utils.call_cmd('. /tmp/tools/setEnv') print ('***** ENV V1 *****') utils.call_cmd('activateEnv v1') o = utils.call_cmd('rootCmd.sh') print(o) print ('***** ENV V2 *****') utils.call_cmd('activateEnv v2') o = utils.call_cmd('rootCmd.sh') print(o)
~$ python3 /tmp/python/script_OK.py
***** ENV V1 *****
runing rootCmd : /tmp/tools/envs/cmds/common/rootCmd.sh
calling subCmd : /tmp/tools/envs/cmds/v1/convert-1.0.3.sh -u http://www.operation.com/api/
convert : trying reaching http://www.operation.com/api/
***** ENV V2 *****
runing rootCmd : /tmp/tools/envs/cmds/common/rootCmd.sh
calling subCmd : /tmp/tools/envs/cmds/v2/inspect-1.4.2.sh -u http://www.audit.com/api/
inspect : trying reaching http://www.audit.com/api/
Dans mon exemple ça n'a pas d'impact. En revanche dans le vrai cas d'usage, setEnv est très très coûteux.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 print ('***** ENV V1 *****') utils.call_cmd('. /tmp/tools/setEnv && activateEnv v1') o = utils.call_cmd('rootCmd.sh') print(o) print ('***** ENV V2 *****') utils.call_cmd('. /tmp/tools/setEnv && activateEnv v2') o = utils.call_cmd('rootCmd.sh') print(o)
Je précise que la solution ne peux pas passer par une modification des shells dans /tmp/tools. Dans mon cas cette partie est fournie et non modifiable.
D'avance merci pour votre aide
Partager