2008-10-15 30 views
227

Tengo un script de Python que necesita ejecutar un programa externo, pero por alguna razón falla.¿Cómo ejecuto un programa desde Python? os.system falla debido a espacios en la ruta

Si tengo el siguiente script:

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

Entonces se produce un error con el siguiente error:

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

Si me escape el programa con citas:

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

Entonces trabajos. Sin embargo, si añado un parámetro, deja de funcionar de nuevo:

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

¿Cuál es la manera correcta de ejecutar un programa y esperar a que se complete? No necesito leer el resultado, ya que es un programa visual que hace un trabajo y luego simplemente sale, pero tengo que esperar a que se complete.

También tenga en cuenta que mover el programa a una ruta no espaciada tampoco es una opción.


Esto no funciona bien:

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

nota las comillas dobles/individuales intercambiadas.

Con o sin un parámetro a la agenda aquí, se produce un error con el mensaje de error

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

+0

Uso esto: 'OS. sistema (r'C: \ temp \ "abc" \ Notepad.exe ') ' o este:' os.system (' C: \\ temp \\ 'abc' \\ Notepad.exe ') ' – chanzerre

Respuesta

248

subprocess.call evitará problemas al tener que lidiar con las convenciones de cotización de varias shells. Acepta una lista, en lugar de una cadena, por lo que los argumentos se delimitan más fácilmente. es decir

import subprocess 
subprocess.call(['C:\\Temp\\a b c\\Notepad.exe', 'C:\\test.txt']) 
+2

Gracias, funcionó muy bien para todos los casos. –

+73

Es mucho más simple para usar cadena sin formato en Windows: r "C: \ Temp \ abc \ Notepad.exe" – PierreBdR

+0

Otra opción puede ser o no usar las funciones exec * que también están en sys de la memoria. Toman una matriz de forma similar , pero no creo que vuelvan nunca. No estoy seguro acerca de la semántica aquí, recuerdo que mencionó que sobrescribió el proceso actual, así que ... –

4

Sospecho que es el mismo problema que cuando se utiliza accesos directos en Windows ... Prueba esto:

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

lo siento, eso tampoco funciona, pregunta editada para reflejar esto. –

+0

Creo que Windows solo usa ", en lugar de" para hacer comillas. Esto probablemente funcionará si cambias esto. Sin embargo, todavía tendrás problemas si tienes citas incrustadas, etc. – Brian

+0

Pensé que tomaban las dos, pero estás probablemente sea correcto. Sé que funciona (en el shell al menos) con comillas dobles. –

58

Aquí hay una manera diferente de hacerlo.

Si está usando Windows, las siguientes acciones hacen doble clic en el archivo en el Explorador o le dan el nombre del archivo como argumento al comando DOS "start": el archivo se abre con cualquier aplicación (si la hay) la extensión está asociada con.

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

Ejemplo:

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

Esto abrirá textfile.txt con el Bloc de notas Bloc de notas si está asociado con los archivos .txt.

+1

¿Existe una función equivalente para los sistemas * nix? – Romeno

+0

@Romeno: podría intentar: 'webbrowser.open (" archivo de texto.txt ")' debería abrir un editor de texto. Ver también [* "iniciar el segundo programa por sí solo, como si simplemente 'hiciera doble clic en él'." *] (Http://stackoverflow.com/a/13078786/4279) – jfs

+0

En mi archivo de texto de configuración. txt debe estar entre comillas, por ejemplo: 'os.startfile ('path \ to \ textfile.txt')' – 10basetom

30

Las comillas exteriores son consumidas por Python, y el shell de Windows no lo ve. Como se mencionó anteriormente, Windows solo entiende las comillas dobles. Python convertirá adelante redujo a barras invertidas en Windows, por lo que puede utilizar

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

El 'es consumido por Python, que luego pasa a 'C: //Temp/abc/Notepad.exe'(como en Windows camino, no hay dobles barras invertidas necesario) para cmd.exe

+1

Esto parece ser el mejor en un escenario como 'os.system ('curl URL> file')' donde quiero para ver la actualización del medidor de progreso de cURL para archivos realmente grandes. –

+0

Si la primera letra después de una barra inversa tiene un significado especial (es decir, '\ t',' \ n', etc.), entonces esa barra diagonal inversa en particular debe duplicarse. Ser una ruta de Windows no tiene nada que ver con eso. –

+1

Tenga en cuenta que si usa 'os.system()' en Windows, la ventana del cmd se abrirá y permanecerá abierta hasta que cierre el proceso que comenzó. En mi humilde opinión, es mejor usar 'os.startfile()'. – 10basetom

15

al menos en Windows 7 y Python 3.1, os.system de Windows quiere que la línea de comandos entre comillas dobles si hay espacios en ruta al comando. Por ejemplo:

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

Un ejemplo del mundo real que se estaba haciendo campaña me clonación de una unidad en VirtualBox. La solución subprocess.call anterior no funcionó debido a algún problema de derechos de acceso, pero cuando comillas dobles-comando, se puso feliz os.system:

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

¡Eso fue todo! Iría por 'subproceso', pero a veces' os.system' y 'os.popen (...). Read()' son más rápidos de escribir. Por cierto, no es necesario que escapes las comillas dobles dentro de una sola, es decir, '' "" C: \\ Temp \\ a b c \\ Notepad.exe "" '' funcionará. –

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

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

y parece que no se necesita cotización con este método, por ejemplo, win32api.WinExec ('pythonw.exe d: \ web2py \ web2py.py -K welcome') inicia el programador web2py en segundo plano. –

+0

@rahul y lo hace, excepto los argumentos para el ejecutable? Entonces, si quiere que el Bloc de notas abra un archivo o se separa? – sayth

0

supuesto de que desea ejecutar el servidor web djnago (en Linux), como fol código bramido:

import subprocess 

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

Si la ruta tiene un espacio, utilizando como código siguiente:

import subprocess 

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

Nota: No se olvide el permiso para acceder a: chmod 777 -R <'yor path'>

Cuestiones relacionadas