icono
¿Hay alguna manera de especificar el directorio de ejecución del comando en Python? subprocess.Popen()
?
Por ejemplo:
Popen('c:\mytool\tool.exe', workingdir="d:\test\local")
Mi secuencia de comandos de Python se encuentra en C:\programs\python
¿Es posible ejecutar C:\mytool\tool.exe
en el directorio D:\test\local
?
¿Cómo configuro el directorio de trabajo para un subproceso?
marca rushakoff
subprocess.Popen
toma una cwd
argumento para configurar el directorio de trabajo actual; también querrá escapar de sus barras invertidas ('d:\\test\\local'
), o usar r'd:\test\local'
para que Python no interprete las barras invertidas como secuencias de escape. La forma en que lo tienes escrito, la \t
parte se traducirá a un pestaña.
Entonces, su nueva línea debería verse así:
subprocess.Popen(r'c:\mytool\tool.exe', cwd=r'd:\test\local')
Para usar su ruta de secuencia de comandos de Python como cwd, import os
y define cwd usando esto:
os.path.dirname(os.path.realpath(__file__))
-
¿Qué efecto, si lo hay, tendría la adición de Shell=True a los argumentos para establecer también el cwd?
– T. Piedra
6 de noviembre de 2009 a las 3:17
-
@T. Stone: Para un ejecutable independiente, no debería cambiar nada, a menos que el exe dependa de algunas variables de entorno en el shell, tal vez. Pero con
shell=False
no puede usar un shell incorporado comocd
: es decir, intente esto en Linux con shell en ambos sentidos:subprocess.Popen("cd /tmp; pwd")
–Mark Rushakoff
6 de noviembre de 2009 a las 3:22
-
Al menos en python 3, no tiene que usar barras invertidas incluso cuando está en una máquina con Windows, acabo de hacerlo
subprocess.call(["C:/Users/Bob/Some.exe"], cwd="C:/Users/Jane/")
y funciona bien– mgrandi
16 de agosto de 2013 a las 21:05
-
¿El directorio de trabajo tiene que ser una ruta absoluta?
– DXsmiley
29 mayo 2015 a las 22:12
-
También funciona para subprocess.check_output(). Gracias !
– Samuel Dauzon
4 de septiembre de 2015 a las 7:15
Otra forma es simplemente hacer esto
cwd = os.getcwd()
os.chdir('c:\some\directory')
subprocess.Popen('tool.exe')
os.chdir(cwd)
Esta solución funciona si desea confiar en rutas relativas, por ejemplo, si la ubicación de su herramienta es c:\some\directory\tool.exe
. cwd
argumento de palabra clave para Popen
no te dejaré hacer esto. Algunas secuencias de comandos/herramientas pueden depender de que usted esté en el directorio dado mientras las invoca. Para hacer que este código sea menos ruidoso, también conocido como separar la lógica relacionada con el cambio de directorios de la “lógica comercial”, puede usar un decorador.
def invoke_at(path: str):
def parameterized(func):
def wrapper(*args, **kwargs):
cwd = os.getcwd()
os.chdir(path)
try:
ret = func(*args, **kwargs)
finally:
os.chdir(cwd)
return ret
return wrapper
return parameterized
Tal decorador se puede usar de una manera:
@invoke_at(r'c:\some\directory')
def start_the_tool():
subprocess.Popen('tool.exe')
-
Tenga en cuenta que puede sortear el problema de la ruta relativa resolviendo primero, por ejemplo, con
Path("../../something").resolve()
. Dicho esto, uso rutinariamentechdir
cuando escribo guiones rápidos, de lo contrario podría escribir en bash.– 2e0byo
12 de enero de 2022 a las 13:20
-
@ 2e0byo Debo admitir que, como desarrollador principalmente de Windows, prefiero Python sobre lote 🙂 Bash no es una opción para mí.
– Ashrasmun
12 de enero de 2022 a las 16:26
-
En realidad, esa es la única forma (o mejor: solución alternativa) que puedo encontrar para “establecer” el directorio de trabajo cuando use Popen. gracias.
– anión
6 de agosto de 2022 a las 9:45
tenga en cuenta que subprocess.call es solo una envoltura delgada sobre subprocess.Popen, y esta envoltura también trata con todos los argumentos de Popen, al menos hasta donde recuerdo 🙂 En casos simples, es mejor apegarse a subprocess.call
– shabunc
31 de octubre de 2013 a las 13:49
Probablemente ahora deberías preferir
subprocess.run
aunquecall
y los envoltorios heredados ligeramente más nuevoscheck_call
ycheck_output
todavía están disponibles.– triplete
27 de diciembre de 2022 a las 17:57