Existe-t-il un moyen simple d'exécuter un script Python sous Windows/Linux/OS X?
Sur les deux derniers, subprocess.Popen("/the/script.py")
fonctionne, mais sur Windows j'obtiens l'erreur suivante:
Traceback (most recent call last):
File "test_functional.py", line 91, in test_functional
log = tvnamerifiy(tmp)
File "test_functional.py", line 49, in tvnamerifiy
stdout = PIPE
File "C:\Python26\lib\subprocess.py", line 595, in __init__
errread, errwrite)
File "C:\Python26\lib\subprocess.py", line 804, in _execute_child
startupinfo)
WindowsError: [Error 193] %1 is not a valid Win32 application
de monkut commentaire : Le cas d'utilisation n'est pas clair. Pourquoi utiliser un sous-processus pour exécuter un script python? Y a-t-il quelque chose qui vous empêche d'importer le script et d'appeler la fonction nécessaire?
J'écrivais un script rapide pour tester la fonctionnalité globale d'un outil en ligne de commande Python (pour le tester sur différentes plates-formes). Fondamentalement, il devait créer un tas de fichiers dans un dossier temporaire, exécuter le script à ce sujet et vérifier que les fichiers étaient renommés correctement.
J'aurais pu importer le script et appeler la fonction, mais comme il repose sur sys.argv
Et utilise sys.exit()
, j'aurais dû faire quelque chose comme ..
import sys
import tvnamer
sys.argv.append("-b", "/the/folder")
try:
tvnamer.main()
except BaseException, errormsg:
print type(errormsg)
De plus, je voulais capturer la stdout et la stderr pour le débogage en cas de problème.
Bien sûr, une meilleure façon serait d'écrire le script de manière plus testable par unité, mais le script est essentiellement "terminé" et je fais un dernier lot de tests avant de faire une version "1.0" (après quoi je vais pour faire une réécriture/restructuration, qui sera beaucoup plus ordonnée et plus testable)
Fondamentalement, il était beaucoup plus facile d'exécuter simplement le script en tant que processus, après avoir trouvé la variable sys.executable
. Je l'aurais écrit sous forme de script Shell, mais cela n'aurait pas été multiplateforme. Le script final peut être trouvé ici
Viens juste de trouver sys.executable
- le chemin complet vers l'exécutable Python exécutable, qui peut être utilisé pour exécuter le script (au lieu de s'appuyer sur le shbang, qui ne fonctionne évidemment pas sous Windows)
import sys
import subprocess
theproc = subprocess.Popen([sys.executable, "myscript.py"])
theproc.communicate()
Que dis-tu de ça:
import sys
import subprocess
theproc = subprocess.Popen("myscript.py", Shell = True)
theproc.communicate() # ^^^^^^^^^^^^
Cela indique à subprocess
d'utiliser le shell du système d'exploitation pour ouvrir votre script et fonctionne sur tout ce que vous pouvez simplement exécuter dans cmd.exe.
De plus, cela recherchera dans le CHEMIN "myscript.py" - ce qui pourrait être souhaitable.
Oui subprocess.Popen(cmd, ..., Shell=True)
fonctionne comme un charme. Sous Windows, le .py
l'extension de fichier est reconnue, donc Python est invoqué pour le traiter (sur * NIX juste le Shebang habituel). L'environnement du chemin contrôle si les choses sont vues. Donc le premier argument de Popen
est juste le nom du script.
subprocess.Popen(['myscript.py', 'arg1', ...], ..., Shell=True)
Il semble que Windows essaie d'exécuter le script en utilisant son propre framework EXE plutôt que de l'appeler comme
python /the/script.py
Essayer,
subprocess.Popen(["python", "/the/script.py"])
Edit: "python" devrait être sur votre chemin.
Vous utilisez un séparateur de chemin qui dépend de la plate-forme. Windows utilise "\" et Unix utilise "/".
Par exemple, pour exécuter le suivant avec l'invite de commande ou le fichier BATCH, nous pouvons utiliser ceci:
C:\Python27\python.exe "C:\Program files(x86)\dev_appserver.py" --Host 0.0.0.0 --post 8080 "C:\blabla\"
Même chose avec Python, on peut faire ça:
subprocess.Popen(['C:/Python27/python.exe', 'C:\\Program files(x86)\\dev_appserver.py', '--Host', '0.0.0.0', '--port', '8080', 'C:\\blabla'], Shell=True)
ou
subprocess.Popen(['C:/Python27/python.exe', 'C:/Program files(x86)/dev_appserver.py', '--Host', '0.0.0.0', '--port', '8080', 'C:/blabla'], Shell=True)
Lorsque vous exécutez un script python sur les fenêtres du sous-processus, vous devez utiliser python devant le nom du script. Essayez:
process = subprocess.Popen("python /the/script.py")