2008-10-15 4 views
227

J'ai un script Python qui doit exécuter un programme externe, mais échoue pour une raison quelconque.Comment exécuter un programme à partir de Python? os.system échoue en raison d'espaces dans le chemin

Si je le script suivant:

import os; 
os.system("C:\\Temp\\a b c\\Notepad.exe"); 
raw_input(); 

Ensuite, il échoue avec l'erreur suivante:

'C:\Temp\a' is not recognized as an internal or external command, operable program or batch file.

Si j'échapper le programme avec des citations:

import os; 
os.system('"C:\\Temp\\a b c\\Notepad.exe"'); 
raw_input(); 

Ensuite, travaux. Cependant, si j'ajoute un paramètre, il cesse de fonctionner à nouveau:

import os; 
os.system('"C:\\Temp\\a b c\\Notepad.exe" "C:\\test.txt"'); 
raw_input(); 

Quelle est la bonne façon d'exécuter un programme et d'attendre qu'elle se termine? Je n'ai pas besoin d'en lire les résultats, car c'est un programme visuel qui fait un travail et qui se termine juste, mais je dois attendre que cela se termine.

Notez également que déplacer le programme vers un chemin non-espacé n'est pas non plus une option.


Cela ne fonctionne pas non plus:

import os; 
os.system("'C:\\Temp\\a b c\\Notepad.exe'"); 
raw_input(); 

Notez les simples/doubles guillemets permutées.

Avec ou sans un paramètre au bloc-notes ici, il échoue avec le message d'erreur

The filename, directory name, or volume label syntax is incorrect.

+0

Utilisez ceci: 'os. système (r'C: \ temp \ "abc" \ Notepad.exe ') ' ou ceci:' os.system (' C: \\ temp \\ "abc" \\ Notepad.exe ') ' – chanzerre

Répondre

248

subprocess.call permettra d'éviter les problèmes de devoir traiter avec des conventions de citations de diverses coquilles. 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']) 
+2

Merci, cela a bien fonctionné pour tous les cas –

+73

Il est beaucoup plus simple pour utiliser la chaîne brute dans Windows: r "C: \ Temp \ abc \ Notepad.exe" – PierreBdR

+0

Une autre option peut être ou non d'utiliser les fonctions exec * qui sont également dans sys de la mémoire. , mais je ne pense pas qu'ils reviennent jamais, je ne suis pas sûr de la sémantique ici, je me souviens qu'il a mentionné écraser le processus actuel, donc ... –

4

Je soupçonne que ce problème est le mê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"); 
+0

désolé, cela ne fonctionne pas non plus, question éditée pour refléter cela. –

+0

Je pense que Windows utilise uniquement ", plutôt que" pour citer, cela fonctionnera probablement si vous changez ceci, mais vous rencontrerez quand même des problèmes avec si vous avez des citations incorporées etc. – Brian

+0

Je pensais que ça prenait les deux, mais vous êtes Je sais que cela fonctionne (dans la coquille au moins) avec des guillemets –

58

Voici une manière différente de le faire. Si vous utilisez Windows, les opérations suivantes consistent à double-cliquer sur le fichier dans l'Explorateur ou à donner le nom du fichier en argument à la commande DOS "start": le fichier est ouvert avec n'importe quelle application (le cas échéant) l'extension est associée à.

filepath = 'textfile.txt' 
import os 
os.startfile(filepath) 

Exemple:

import os 
os.startfile('textfile.txt') 

Cela ouvrira textfile.txt avec le Bloc-notes si le Bloc-notes est associée à des fichiers txt.

+1

Existe-t-il une fonction équivalente pour les systèmes * nix? – Romeno

+0

@Romeno: vous pouvez essayer: 'webbrowser.open (" textfile.txt ")' cela devrait ouvrir un éditeur de texte. Voir aussi [* "démarrer complètement le second programme, comme si je" double-cliquais dessus "." *] (Http://stackoverflow.com/a/13078786/4279) – jfs

+0

Sur mon fichier texte d'installation. txt doit être entre guillemets, par exemple: 'os.startfile ('path \ to \ textfile.txt')' – 10basetom

30

Les guillemets les plus externes sont consommés par Python lui-même et le shell Windows ne le voit pas. Comme mentionné ci-dessus, Windows comprend uniquement les guillemets doubles. Python convertira en avant-tailladé à antislashs sous Windows, vous pouvez donc utiliser

os.system('"C://Temp/a b c/Notepad.exe"') 

Le 'est consommé par Python, qui passe alors « C: //Temp/abc/Notepad.exe » (comme Windows chemin, pas de double barre oblique inverse nécessaire) pour cmd.exe

+1

Cela semble le meilleur dans un scénario comme 'os.system ('curl URL> fichier')' où je veux pour voir l'actualisation du compteur de progression de cURL pour les gros fichiers. –

+0

Si la première lettre après un antislash a une signification spéciale (c'est-à-dire '\ t',' \ n', etc.) alors cette barre oblique inverse doit être doublée. Être un chemin Windows n'a rien à voir avec ça. –

+1

Notez que si vous utilisez 'os.system()' sous Windows, la fenêtre cmd s'ouvrira et restera ouverte jusqu'à la fermeture du processus initial. À mon humble avis, il est préférable d'utiliser 'os.startfile()'. – 10basetom

15

au moins dans Windows 7 et Python 3.1, os.system dans Windows veut double cité la ligne de commande s'il y a des espaces dans le chemin de la commande. Par exemple:

TheCommand = '\"\"C:\\Temp\\a b c\\Notepad.exe\"\"' 
    os.system(TheCommand) 

Un exemple réel qui me bloquait était le clonage d'un lecteur dans VirtualBox. La solution subprocess.call ci-dessus ne fonctionne pas à cause d'un problème de droits d'accès, mais quand je double citais la commande, os.system est devenu heureux:

TheCommand = '\"\"C:\\Program Files\\Sun\\VirtualBox\\VBoxManage.exe\" ' \ 
       + ' clonehd \"' + OrigFile + '\" \"' + NewFile + '\"\"' 
    os.system(TheCommand) 
+0

C'était tout! J'opterais pour 'subprocess', mais parfois' os.system' et 'os.popen (...). Read()' sont juste plus rapides à taper. BTW, vous n'avez pas besoin d'échapper les guillemets doubles à l'intérieur d'un seul, c'est à dire '' "" C: \\ Temp \\ a b c \\ Notepad.exe "" ''fera l'affaire. –

7
import win32api # if active state python is installed or install pywin32 package seperately 

try: win32api.WinExec('NOTEPAD.exe') # Works seamlessly 
except: pass 
+0

et il semble que cette méthode ne nécessite pas de guillemets, par exemple win32api.WinExec ('pythonw.exe d: \ web2py \ web2py.py -K welcome') démarre le planificateur web2py en arrière-plan. –

+0

@rahul et le fait à l'exception des arguments pour l'exécutable? Donc, si vous voulez que le Bloc-notes ouvre un fichier ou est-ce séparé? – sayth

0

Supposons que vous souhaitez exécuter votre serveur Web djnago (sous linux), comme fol Code mugissement:

import subprocess 

args = ['{}/manage.py'.format('/home/<you>/<path>'), 'runserver'] 
subprocess.Popen(args, stdout=subprocess.PIPE).poll() 

Si votre chemin a un espace, en utilisant par exemple le code suivant:

import subprocess 

args = ['{}'.format('/home/<you>/<first path section> <second path section>')] 
subprocess.Popen(args, stdout=subprocess.PIPE).poll() 

Note: Ne pas oublier la permission accès: chmod 777 -R <'yor path'>

Questions connexes