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

2024-03-18 10:18:51 +08:00
 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 的方法。

905 次点击
所在节点    问与答
14 条回复
ysc3839
2024-03-18 11:41:47 +08:00
根据 CreateProcessW 文档的说法,是不会去参数里指定的 cwd 搜索可执行文件的,只会在当前进程的 cwd 中搜索。
https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
chenqh
2024-03-18 11:42:42 +08:00
为什么不使用绝对路径呢?
nyxsonsleep
2024-03-18 11:54:31 +08:00
@chenqh 这里不希望使用绝对路径。而且用 shell=True 就不用绝对路径也能执行。
而且如果改变 os.environ 的 PATH 参数,就能不在绝对路径的情况下执行了。
这个函数的行为比较奇怪。
nyxsonsleep
2024-03-18 11:56:28 +08:00
@ysc3839 如果改变 os.environ 有效,但是改变 env 参数无效又是为什么呢?
ysc3839
2024-03-18 12:03:25 +08:00
@nyxsonsleep 因为也只会在当前进程的 PATH 中搜索,不会去参数里指定的 PATH 搜索
rrfeng
2024-03-18 12:33:53 +08:00
最好写一个方法获取当前路径,然后拼接成绝对路径。
nyxsonsleep
2024-03-18 14:31:27 +08:00
@ysc3839 env 参数是环境变量。env 都不搜索,那这个 env 意义是什么?
ysc3839
2024-03-18 15:39:51 +08:00
@nyxsonsleep 我试了一下,POSIX exec 带 envp 的版本也不会在 envp 的 PATH 里搜索,所以微软只是保持了和 POSIX 行为一致,具体原因你得问 POSIX 了。
https://man7.org/linux/man-pages/man3/exec.3p.html
lambdaq
2024-03-18 15:46:06 +08:00
你这 cwd=r'C:/tmp' 已经改了当前目录了。 确认 C:/tmp/h.bat 存在吗?
nyxsonsleep
2024-03-18 17:10:47 +08:00
@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
2024-03-18 17:11:07 +08:00
@lambdaq 这是肯定的
lambdaq
2024-03-18 17:15:53 +08:00
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
2024-03-18 17:35:33 +08:00
@nyxsonsleep 我自己测试了,并没有问题
ipwx
2024-03-18 17:45:27 +08:00
加一个 cmd.exe 怎么样。

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

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

https://yangjunhui.monster/t/1024604

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

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

© 2021 V2EX