Python subprocess.run 无法执行当前目录下的可执行文件

283 天前
 nyxsonsleep
# C:/tmp/h.bat exist.
subprocess.run(["h.bat"],cwd=r'C:/tmp', shell=False)

报错FileNotFoundError: [WinError 2] 系统找不到指定的文件。

  1. 不能使用 shell=True ,这种情况下可以执行 h.bat ,但是 review 要求不能使用。
  2. 尝试了改变 run 函数的 env 参数,但是无效。可以减少内容,但是不能改变内容。不明原因

寻求一种方法直接可以运行 subprocess.run 函数直接执行 h.bat 的方法。

791 次点击
所在节点    问与答
14 条回复
ysc3839
283 天前
根据 CreateProcessW 文档的说法,是不会去参数里指定的 cwd 搜索可执行文件的,只会在当前进程的 cwd 中搜索。
https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
chenqh
283 天前
为什么不使用绝对路径呢?
nyxsonsleep
283 天前
@chenqh 这里不希望使用绝对路径。而且用 shell=True 就不用绝对路径也能执行。
而且如果改变 os.environ 的 PATH 参数,就能不在绝对路径的情况下执行了。
这个函数的行为比较奇怪。
nyxsonsleep
283 天前
@ysc3839 如果改变 os.environ 有效,但是改变 env 参数无效又是为什么呢?
ysc3839
283 天前
@nyxsonsleep 因为也只会在当前进程的 PATH 中搜索,不会去参数里指定的 PATH 搜索
rrfeng
283 天前
最好写一个方法获取当前路径,然后拼接成绝对路径。
nyxsonsleep
283 天前
@ysc3839 env 参数是环境变量。env 都不搜索,那这个 env 意义是什么?
ysc3839
283 天前
@nyxsonsleep 我试了一下,POSIX exec 带 envp 的版本也不会在 envp 的 PATH 里搜索,所以微软只是保持了和 POSIX 行为一致,具体原因你得问 POSIX 了。
https://man7.org/linux/man-pages/man3/exec.3p.html
lambdaq
283 天前
你这 cwd=r'C:/tmp' 已经改了当前目录了。 确认 C:/tmp/h.bat 存在吗?
nyxsonsleep
283 天前
@ysc3839 但是我添加 env 参数如果是删除 PATH 中的个别字段是生效的。
比如我在系统环境变量中添加了 C:/tmp ,可以直接
```
subprocess.run(["h.bat"],cwd=r'C:/tmp', shell=False) # 可以直接执行
```
但此时如果像下面这样删除环境变量中的部分字段,又无法再次搜索到 h.bat
```
new_env = os.environ.copy()
new_env["PATH"].replace('C:/tmp;','')
subprocess.run(["h.bat"],cwd=r'C:/tmp',env=new_env)
```
奇怪的是如果反过来,系统环境变量中并没有'C:/tmp',但是在 env 中添加,这个字段不会生效。
```
new_env = os.environ.copy()
new_env["PATH"]='C:/tmp;'+new_env["PATH"]
subprocess.run(["h.bat"],cwd=r'C:/tmp',env=new_env)
```

这又是什么原理?
nyxsonsleep
283 天前
@lambdaq 这是肯定的
lambdaq
283 天前
note that when resolving or searching for the executable path with shell=False, cwd does not override the current working directory and env cannot override the PATH environment variable


文档写得挺仔细。 @nyxsonsleep
ysc3839
283 天前
@nyxsonsleep 我自己测试了,并没有问题
ipwx
283 天前
加一个 cmd.exe 怎么样。

可能是 ["cmd.exe", "/C", "h.bat"]

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1024604

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX