如何为子进程指定工作目录

249 投票
2 回答
268449 浏览
提问于 2025-04-15 15:43

有没有办法在Python的 subprocess.Popen() 中指定命令的运行目录?

举个例子:

Popen('c:\mytool\tool.exe', workingdir='d:\test\local')

我的Python脚本放在 C:\programs\python 这个位置。

我能否在 D:\test\local 这个目录下运行 C:\mytool\tool.exe 呢?

我该如何为一个子进程设置工作目录?

2 个回答

12

另一种方法就是简单地这样做

cwd = os.getcwd()
os.chdir('c:\some\directory')
subprocess.Popen('tool.exe')
os.chdir(cwd)

这个解决方案适合你想使用相对路径的情况,比如说,如果你的工具位置是 c:\some\directory\tool.exe。使用 Popencwd 关键字参数会让你无法这样做。有些脚本或工具可能需要你在特定目录下运行它们。为了让这段代码看起来更简洁,也就是把改变目录的逻辑和“业务逻辑”分开,你可以使用一个装饰器。

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            

这样的装饰器可以这样使用:

@invoke_at(r'c:\some\directory')
def start_the_tool():
    subprocess.Popen('tool.exe')
367

subprocess.Popen 这个函数有一个参数叫 cwd,它用来设置当前工作目录。你还需要处理一下你的反斜杠(比如 'd:\\test\\local'),或者使用 r'd:\test\local' 这样写,这样反斜杠就不会被 Python 误解为特殊字符了。你现在写的方式中,\t 会被当成一个 tab 键。

所以,你的新写法应该是这样的:

subprocess.Popen(r'c:\mytool\tool.exe', cwd=r'd:\test\local')

如果你想把你的 Python 脚本路径当作当前工作目录,先 import os,然后用下面的方式定义 cwd

os.path.dirname(os.path.realpath(__file__)) 

撰写回答