Comment exécuter un programme depuis Python? os.system échoue à cause d'espaces dans le chemin
-
03-07-2019 - |
Question
J'ai un script Python qui doit exécuter un programme externe, mais pour une raison quelconque échoue.
Si j'ai le script suivant:
import os;
os.system("C:\\Temp\\a b c\\Notepad.exe");
raw_input();
Il échoue ensuite avec l'erreur suivante:
'C: \ Temp \ a' n'est pas reconnu comme une commande interne ou externe, un programme utilisable ou un fichier de commandes.
Si j'échappe au programme avec des guillemets:
import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe"');
raw_input();
Ensuite, ça marche. Cependant, si j’ajoute un paramètre, il ne fonctionne plus:
import os;
os.system('"C:\\Temp\\a b c\\Notepad.exe" "C:\\test.txt"');
raw_input();
Quel est le bon moyen d'exécuter un programme et d'attendre qu'il se termine? Je n'ai pas besoin de lire le résultat, car il s'agit d'un programme visuel qui effectue un travail, puis se ferme, mais je dois attendre qu'il soit terminé.
Notez également que le déplacement du programme vers un chemin non espacé n’est pas une option non plus.
Cela ne fonctionne pas non plus:
import os;
os.system("'C:\\Temp\\a b c\\Notepad.exe'");
raw_input();
Notez les guillemets simples / doubles échangés.
Avec ou sans paramètre à Notepad ici, cela échoue avec le message d'erreur
Le nom du fichier, le nom du répertoire ou la syntaxe du libellé de volume est incorrect.
La solution
subprocess.call
évitera les problèmes d'avoir à traiter avec les conventions de citations de divers obus. Il accepte une liste plutôt qu'une chaîne, de sorte que les arguments sont plus facilement délimités. c'est-à-dire
import subprocess
subprocess.call(['C:\\Temp\\a b c\\Notepad.exe', 'C:\\test.txt'])
Autres conseils
Voici une manière différente de le faire.
Si vous utilisez Windows, procédez comme suit: double-cliquez sur le fichier dans l’explorateur ou donnez le nom du fichier en tant qu’argument au DOS " start " commande: le fichier est ouvert avec n'importe quelle application (le cas échéant) associée à l'extension.
filepath = 'textfile.txt'
import os
os.startfile(filepath)
Exemple:
import os
os.startfile('textfile.txt')
Ceci ouvrira textfile.txt avec le Bloc-notes si celui-ci est associé à des fichiers .txt.
Les citations les plus externes sont utilisées par Python lui-même et le shell Windows ne les voit pas. Comme mentionné ci-dessus, Windows ne comprend que les guillemets doubles. Python convertira les barres obliques inverses sous Windows afin que vous puissiez utiliser
os.system('"C://Temp/a b c/Notepad.exe"')
Le 'est consommé par Python, qui passe ensuite " C: // Temp / a b c / Notepad.exe " (en tant que chemin Windows, aucune double barre oblique inversée n'est nécessaire) vers CMD.EXE
Au moins dans Windows 7 et Python 3.1, os.system
dans Windows souhaite la ligne de commande entre guillemets s'il y a des espaces dans le chemin d'accès à la commande. Par exemple:
TheCommand = '\"\"C:\\Temp\\a b c\\Notepad.exe\"\"'
os.system(TheCommand)
Un exemple concret qui me bouleversait était le clonage d'un lecteur dans VirtualBox. La subprocess.call
solution ci-dessus n'a pas fonctionné à cause d'un problème de droits d'accès, mais lorsque j'ai double-cité la commande, <=> est devenu heureux:
TheCommand = '\"\"C:\\Program Files\\Sun\\VirtualBox\\VBoxManage.exe\" ' \
+ ' clonehd \"' + OrigFile + '\" \"' + NewFile + '\"\"'
os.system(TheCommand)
import win32api # if active state python is installed or install pywin32 package seperately
try: win32api.WinExec('NOTEPAD.exe') # Works seamlessly
except: pass
Je suppose que c'est le même problème que lorsque vous utilisez des raccourcis dans Windows ... Essayez ceci:
import os;
os.system("\"C:\\Temp\\a b c\\Notepad.exe\" C:\\test.txt");
Pour python > = 3.5 subprocess.run
doit être utilisé à la place de subprocess.call
https://docs.python.org /3/library/subprocess.html#older-high-level-api
import subprocess
subprocess.run(['notepad.exe', 'test.txt'])
Supposons que nous voulions faire fonctionner votre serveur Web Django (sous Linux) s'il y avait un espace entre votre chemin (chemin = '/home/<you>/<first-path-section> <second-path-section>'
), procédez ainsi:
import subprocess
args = ['{}/manage.py'.format('/home/<you>/<first-path-section> <second-path-section>'), 'runserver']
res = subprocess.Popen(args, stdout=subprocess.PIPE)
output, error_ = res.communicate()
if not error_:
print(output)
else:
print(error_)
[ Remarque ]:
- N'oubliez pas l'accès:
chmod 755 -R <'yor path'>
-
manage.py
est remplaçable:chmod +x manage.py