subprocess.call 与 os.system 在 Python 中的区别

1 投票
1 回答
3787 浏览
提问于 2025-04-17 14:29

这是我第一次在这里提问:

我需要在Windows上映射一个网络驱动器。这个位置是一个内部的SharePoint文档库。

在命令提示符窗口中:

net use g: http://na.com/DMP/DMP/programming/

成功了 --> 这个命令执行成功了

os.system('"net use k: http://na.com/DMP/DMP/programming/"')

这个也成功了。

不过,我想用subprocess.call来处理这种情况,如果这个驱动器已经被映射了,我想尝试映射另一个驱动器。

call(["net", "use", ":q", '"http://na.com/DMP/DMP/programming/"'])

但是这样做失败了,出现了“系统错误67:找不到网络名称”的提示。我尝试了很多选项,但都没有成功。

有没有什么办法可以让我成功完成这个操作,或者有没有其他方法可以映射驱动器?

1 个回答

3

你的代码里至少有两个问题:

call(["net", "use", ":q", '"http://na.com/DMP/DMP/programming/"'])

首先,你写成了 ":q",其实应该是 "q:"。这样可能会导致 net 命令把 :q 当成你的网络位置,而不是你想要的目标驱动器,这样就可能出现错误67。

其次,你在网址周围多加了一对引号:'"http://na.com/DMP/DMP/programming/"',其实应该用 'http://na.com/DMP/DMP/programming/'。当 subprocess 生成要传给 CreateProcess 的字符串时,它已经会给每个参数加上引号。如果你自己再加一次引号,就会变成双重引号。在某些情况下,这在Windows上是行不通的,可能会导致一些问题,但我觉得在这里不是这种情况。你最终会把这个带引号的字符串成功传给 net,告诉它你想打开一个以 "http: 开头的相对路径或者一个带有 "http 协议的URL,或者类似的东西。不管怎样,这不是一个有效的网络位置,很可能会导致错误67。

正如Ben指出的,你的 system 调用也有类似的问题——你在整个字符串周围多加了一对引号。如果你真的想搞清楚,可能有某种原因让这个方法有效……但我觉得你并不想去弄明白。就把它当作“我做错了,但运气好”,以后别再这样做了。

最后,正如文档所说:

在Windows上,参数序列会被转换成可以解析的字符串

这意味着,如果你已经有一个在Windows上能正常工作的命令行,直接把它当作字符串使用会更好,而不是试图把它拆分成一个序列让 subprocess 重新组合。

(请记住,这只适用于Windows!在其他平台上,subprocess 会构建一个字符串数组,传给 CreateProcess 家族的函数。)

所以,直接这样做:

call("net use g: http://na.com/DMP/DMP/programming/")

撰写回答