# C:/tmp/h.bat exist.
subprocess.run(["h.bat"],cwd=r'C:/tmp', shell=False)
报错FileNotFoundError: [WinError 2] 系统找不到指定的文件。
寻求一种方法直接可以运行 subprocess.run 函数直接执行 h.bat 的方法。
1
ysc3839 283 天前 via Android
根据 CreateProcessW 文档的说法,是不会去参数里指定的 cwd 搜索可执行文件的,只会在当前进程的 cwd 中搜索。
https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw |
2
chenqh 283 天前
为什么不使用绝对路径呢?
|
3
nyxsonsleep OP @chenqh 这里不希望使用绝对路径。而且用 shell=True 就不用绝对路径也能执行。
而且如果改变 os.environ 的 PATH 参数,就能不在绝对路径的情况下执行了。 这个函数的行为比较奇怪。 |
4
nyxsonsleep OP @ysc3839 如果改变 os.environ 有效,但是改变 env 参数无效又是为什么呢?
|
5
ysc3839 283 天前 via Android
@nyxsonsleep 因为也只会在当前进程的 PATH 中搜索,不会去参数里指定的 PATH 搜索
|
6
rrfeng 283 天前
最好写一个方法获取当前路径,然后拼接成绝对路径。
|
7
nyxsonsleep OP @ysc3839 env 参数是环境变量。env 都不搜索,那这个 env 意义是什么?
|
8
ysc3839 282 天前 via Android
@nyxsonsleep 我试了一下,POSIX exec 带 envp 的版本也不会在 envp 的 PATH 里搜索,所以微软只是保持了和 POSIX 行为一致,具体原因你得问 POSIX 了。
https://man7.org/linux/man-pages/man3/exec.3p.html |
9
lambdaq 282 天前
你这 cwd=r'C:/tmp' 已经改了当前目录了。 确认 C:/tmp/h.bat 存在吗?
|
10
nyxsonsleep OP @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) ``` 这又是什么原理? |
11
nyxsonsleep OP @lambdaq 这是肯定的
|
12
lambdaq 282 天前
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 |
13
ysc3839 282 天前 via Android
@nyxsonsleep 我自己测试了,并没有问题
|
14
ipwx 282 天前
加一个 cmd.exe 怎么样。
可能是 ["cmd.exe", "/C", "h.bat"] |