¿Cómo puedo especificar el directorio de trabajo para un subproceso?

3 minutos de lectura

avatar de usuario de icn
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?

  • 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.runaunque call y los envoltorios heredados ligeramente más nuevos check_call y check_output todavía están disponibles.

    – triplete

    27 de diciembre de 2022 a las 17:57

Avatar de usuario de Mark Rushakoff
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=Falseno puede usar un shell incorporado como cd: 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 rutinariamente chdir 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

¿Ha sido útil esta solución?