在UNC路径而非映射驱动器上调用subprocess.Popen()

6 投票
1 回答
6494 浏览
提问于 2025-04-16 12:57

我想运行一个可执行文件,这个文件需要处理一个存放在远程文件服务器上的数据集。在设计的时候,我希望这个文件服务器的位置能够灵活一些,也就是说在我的Python程序运行时可以传递给它。

我写了一段代码来说明我的问题,使用的是python命令,这样任何人都可以运行:

#!/usr/bin/env python
import os
import subprocess

def runMySubProcess(cmdstr, iwd):
    p = subprocess.Popen(cmdstr,
        shell=True,
        cwd=iwd,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
    (stdout, stderr) = p.communicate()
    if stderr:
        raise IOError, stderr
    return stdout

if __name__ == '__main__':
    print runMySubProcess('python -h', 'C:\\')
    print runMySubProcess('python -h', '\\\\htpc\\nas')

这段代码在iwd是一个已经映射到驱动器字母的共享位置时运行得很好。但是如果iwd是一个UNC路径,调用subprocess.Popen()时就会出现错误输出,这会导致IOError异常:

Traceback (most recent call last):
  File "test.py", line 19, in <module>
    print runMySubProcess('dir', '\\\\htpc\\nas')
  File "test.py", line 14, in runMySubProcess
    raise IOError, stderr
IOError: '\\htpc\nas'
CMD.EXE was started with the above path as the current directory.
UNC paths are not supported.  Defaulting to Windows directory.

有没有办法让这个子进程调用在不解析iwd并在机器上创建临时驱动器挂载的情况下工作呢?我想避免管理驱动器挂载的创建和清理。当然,我也不想碰到(虽然不太可能)所有驱动器字母都被占用的情况。

1 个回答

6

问题不在于 Popen,而在于 cmd.exe。它不允许工作目录是一个 UNC 路径。就是不允许,你可以试试看。如果你在调用 Popen() 时指定 shell=False,可能会有更好的结果,前提是你要运行的程序能够处理 UNC 路径。不过,如果你要运行的是 cmd.exe 内置的命令,那就没办法了。

撰写回答