¿Cómo ejecuto un programa desde Python? El sistema os falla debido a espacios en la ruta

StackOverflow https://stackoverflow.com/questions/204017

  •  03-07-2019
  •  | 
  •  

Pregunta

Tengo un script de Python que necesita ejecutar un programa externo, pero por alguna razón falla.

Si tengo el siguiente script:

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

Entonces falla con el siguiente error:

  

'C: \ Temp \ a' no se reconoce como un comando interno o externo, programa operativo o archivo por lotes.

Si escapo del programa con comillas:

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

Entonces funciona. Sin embargo, si agrego un parámetro, deja de funcionar nuevamente:

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

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

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


Esto tampoco funciona:

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

Tenga en cuenta las comillas simples / dobles intercambiadas.

Con o sin un parámetro para el Bloc de notas aquí, falla con el mensaje de error

  

El nombre de archivo, el nombre del directorio o la sintaxis de la etiqueta de volumen es incorrecta.

¿Fue útil?

Solución

subprocess.call evitará problemas con tener que lidiar con las convenciones de citas de varios proyectiles. 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'])

Otros consejos

Aquí hay una forma diferente de hacerlo.

Si está utilizando Windows, lo siguiente actúa como hacer doble clic en el archivo en el Explorador, o dar el nombre del archivo como argumento para el DOS " start " comando: el archivo se abre con cualquier aplicación (si la hay) a la que está asociada su extensión.

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

Ejemplo:

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

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

Python consume las citas más externas, y el shell de Windows no lo ve. Como se mencionó anteriormente, Windows solo entiende comillas dobles. Python convertirá barras diagonales en barras diagonales inversas en Windows, por lo que puede usar

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

El 'es consumido por Python, que luego pasa " C: // Temp / a b c / Notepad.exe " (como ruta de Windows, no se necesitan barras invertidas dobles) a CMD.EXE

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

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

Un ejemplo del mundo real que me estaba confundiendo era clonar una unidad en VirtualBox. La solución subprocess.call anterior no funcionó debido a un problema de derechos de acceso, pero cuando hice una doble cita del comando, <=> me alegré:

  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

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

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

Para python > = 3.5 subprocess.run debe usarse en lugar de subprocess.call

https://docs.python.org /3/library/subprocess.html#older-high-level-api

import subprocess
subprocess.run(['notepad.exe', 'test.txt'])

Supongamos que queremos ejecutar su servidor web Django (en Linux) que hay espacio entre su ruta (ruta = '/home/<you>/<first-path-section> <second-path-section>'), así que haga lo siguiente:

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_)

[ Nota ]:

  • No olvides el permiso de acceso: chmod 755 -R <'yor path'>
  • manage.py es excelente: chmod +x manage.py
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top