Lancement de shell depuis python
Remonter à Forum général Python
-
Bonjour,
J’ai un script python qui génère puis exécute un script shell. Ce script shell doit absolument être sourcé. Pour ca j’utilse la commande:subprocess.call(["command",".",str(ShellFilePath)],shell=True)
ou ShellFilePath est le path de mon shell (en l’occurrence /tmp/chWS.sh). Il se trouve qu’à la fin de ce shell il y a un ‘cd’ vers un Path. Hors, quand j’exécute le script python, je n’ai pas changé de directory à la fin. Par contre, si je lance directement après le script:$>command . /tmp/chWS.sh
Tout se passe bien. J’ai instrumenté le script python en appelant ‘os.spawnlp(os.P_WAIT, 'pwd','pwd')’ avant et après subprocess.call, et la directory correspond toujours à celle d’où est lancé le script python. Pour info j’ai également essayé les syntaxes suivante:cmdToExec='command . '+str(ShellFilePath)
os.system(cmdToExec) //KO
os.spawnlp(os.P_WAIT,cmdToExec,cmdToExec) //KO
subprocess.Popen(str(cmdToExec),0,None,None,None,subprocess.STDOUT,None,False,True,None,None,False,None,0) //KO
J’ai l’impression que tout se passe comme si mon shell était exécuté dans un terminal autre que celui d’où est lancé mon script python.
Quelqu'un peut-il me dépanner?
D'avance merci.-
Python n'y est pour rien, c'est un point basique de Unix (l'isolement des process).
Lorsqu'un process change de répertoire, il est seul à changer ; le changement de répertoire n'est (heureusement) pas transmis ni à son père, ni à ses fils.
Lorsque vous faites :
. script
le script est interprété par le shell courant lui-même, lequel exécute la commande (built-in) "cd" qui le fait changer de répertoire (c'est pourquoi le script doit être "sourcé" ).
Lorsque vous lancez votre script (plus exactement un process shell qui interprètera votre script) par subprocess.call(), le "cd" est bien exécuté par le process shell, mais il ne "remonte" pas au process père, qui est l'interpréteur Python. C'est comme si, sous un shell, vous lanciez le script au lieu de le "sourcer".
Ce que vous voulez faire est impossible : par nature votre script, écrit en langage shell, doit être exécuté par un process différent de l'interpréteur Python, exécutant un programme différent (le shell au lieu de Python) -> le "cd" exécuté par le shell ne pourra jamais avoir d'influence sur l'interpréteur Python. -
Merci Jacko pour cette réponse claire. Je comprends mieux. En fait ce qui m'intéresse c'est d'avoir un shell avec un environnement modifié par mon batch (export de variable et changement de directory courante) dans lequel je pourrais exécuter d'autres commandes (et éventuellement récupérer les traces, mais ça c'est la cerise sur le gâteau
).
Existe-t-il donc une alternative pour pouvoir garder un handle sur le terminal où le shell a été exécuté, et pouvoir s'en servir ultérieurement pour exécuter d'autre commande?
D'avance merci pour votre aide. -
Bonjour,
Oubliez cette notion de terminal : python et votre shell utilisent le même terminal.
Une solution serait de communiquer avec le shell par un pipe :
- lancer le shell en redirigeant son entrée standard sur un pipe.
- envoyer toutes les commandes par ce pipe.
p=subprocess.Popen("sh",stdin=subprocess.PIPE)
p.stdin.write("cd monrepertoire\n")
p.stdin.write("VAR=xxx\n")
p.stdin.write("prog arg\n")
Si vous avez un script tout fait, qq chose comme :
p.stdin.write(open("script" ).read())
devrait fonctionner.
Si vous voulez récupérer la sortie du shell (et des programmes lancés par lui), vous pouvez rediriger de la même façon sa sortie standard stdout. Mais attention aux problèmes de dead-lock.
-
Rendu par Ploneboard
