J'écris un script python qui vérifie diverses conditions et exécute un script powershell en conséquence pour m'aider à automatiser la migration de windows XP vers windows 7. Le script powershell donne sa propre sortie donnant à l'utilisateur des mises à jour sur ce qui se passe. Je voudrais prendre la sortie du script powershell et l'imprimer comme sortie du script python. J'ai regardé autour de quelques questions qui semblent vouloir faire la même chose mais ils ne semblent pas fonctionner pour moi. Au début, j'ai essayé d'utiliser
import subprocess
subprocess.call(["C:\Users\gu2124\Desktop\helloworld.ps1"])
Comme cela a été suggéré ici Exécuter la fonction PowerShell à partir de Python mais j'ai découvert que cela attend que le programme s'exécute en premier et ne donne pas de sortie, j'ai donc découvert que j'avais besoin d'utiliser subprocess.Popen()
comme cela a été suggéré ici tilisez Popen pour exécuter un script Powershell en Python, comment puis-je obtenir la sortie du script Powershell et le mettre à jour sur la page Web? alors j'ai essayé ceci
import subprocess
subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=sys.stdout)
et je reçois cette erreur
Traceback (most recent call last):
File "C:\Users\gu2124\Desktop\pstest.py", line 5, in <module>
subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.py1"], stdout=sys.stdout)
File "C:\Python27\lib\subprocess.py", line 701, in __init__
errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
File "C:\Python27\lib\subprocess.py", line 848, in _get_handles
c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
File "<string>", line 523, in __getattr__
File "C:\Program Files\PyScripter\Lib\rpyc.Zip\rpyc\core\netref.py", line 150, in __getattr__
return syncreq(self, consts.HANDLE_GETATTR, name)
File "C:\Program Files\PyScripter\Lib\rpyc.Zip\rpyc\core\netref.py", line 71, in syncreq
return conn.sync_request(handler, oid, *args)
File "C:\Program Files\PyScripter\Lib\rpyc.Zip\rpyc\core\protocol.py", line 434, in sync_request
raise obj
AttributeError: DebugOutput instance has no attribute 'fileno'
Je ne suis pas complètement sûr de ce que cela signifie, mais d'après ce que je pense avoir compris après avoir lu ceci AttributeError: l'instance de StringIO n'a pas d'attribut 'fileno' c'est que c'est parce que je joue avec la stdout de manière incorrecte. J'ai regardé un peu plus et j'ai trouvé cela Pourquoi mon code de sous-processus python ne fonctionne-t-il pas? où les réponses ont dit d'utiliser stdout=subprocess.PIPE
Alors j'ai essayé ce
import subprocess
subprocess.Popen(["C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=subprocess.PIPE)
qui ne me donne pas non plus de sortie Enfin, j'ai vu cela http://www.pythonforbeginners.com/os/subprocess-for-system-administrators et j'ai changé mon code en celui-ci
import subprocess
p = subprocess.Popen(["powershell","C:\Users\gu2124\Desktop\helloworld.ps1"], stdout=subprocess.PIPE)
print p.communicate
Je pensais que cela le pouvait parce que j'essaie initialement d'exécuter un script PowerShell à partir de la ligne de commande, je dois donc d'abord ouvrir PowerShell. Lorsque je tape ces commandes directement dans la ligne de commande, cela fonctionne comme il se doit, mais lorsque je l'exécute via le script python, il donne ceci
<bound method Popen.communicate of <subprocess.Popen object at 0x00000000026E4A90>>
ce qui est une amélioration je suppose mais pas le "Hello world" que j'attendais. Je n'ai aucune idée de ce que je devrais essayer de faire ensuite pour que cela fonctionne. Toute aide serait grandement appréciée
De plus, si le script PowerShell que j'utilise est nécessaire ici, il est
$strString = "Hello World"
write-Host $strString
function ftest{
$test = "Test"
write-Host $test
}
EDIT: J'ai essayé de mettre à niveau vers python 3.3 comme cela a été suggéré dans la première réponse mais je ne peux toujours pas le faire fonctionner. J'ai utilisé la commande p = subprocess.Popen(['powershell.exe', "C:\\Users\\gu2124\\Desktop\\helloworld.ps1"], stdout=sys.stdout)
et je suis sûr que le le fichier est là mais j'obtiens cette erreur:
Traceback (most recent call last):
File "<pyshell#3>", line 1, in <module>
p = subprocess.Popen(['powershell.exe', "C:\\Users\\gu2124\\Desktop\\helloworld.ps1"], stdout=sys.stdout)
File "C:\Python27\lib\subprocess.py", line 701, in __init__
errread, errwrite), to_close = self._get_handles(stdin, stdout, stderr)
File "C:\Python27\lib\subprocess.py", line 848, in _get_handles
c2pwrite = msvcrt.get_osfhandle(stdout.fileno())
UnsupportedOperation: fileno
Assurez-vous que vous pouvez exécuter des scripts PowerShell (il est désactivé par défaut). Vous l'avez probablement déjà fait. http://technet.Microsoft.com/en-us/library/ee176949.aspx
Set-ExecutionPolicy RemoteSigned
Exécutez ce script python sur votre script powershell helloworld.py
:
# -*- coding: iso-8859-1 -*-
import subprocess, sys
p = subprocess.Popen(["powershell.exe",
"C:\\Users\\USER\\Desktop\\helloworld.ps1"],
stdout=sys.stdout)
p.communicate()
Ce code est basé sur python3.4 (ou n'importe quel interpréteur de série 3.x), bien qu'il devrait également fonctionner sur la série python2.x.
C:\Users\MacEwin\Desktop>python helloworld.py
Hello World
Je n'ai pas Python 2.7 installé, mais dans Python 3.3 appelant Popen
avec stdout
réglé sur sys.stdout
a très bien fonctionné. Mais pas avant d'avoir échappé aux barres obliques inverses du chemin.
>>> import subprocess
>>> import sys
>>> p = subprocess.Popen(['powershell.exe', 'C:\\Temp\\test.ps1'], stdout=sys.stdout)
>>> Hello World
_