I'm building a tool which spawns a shell process. Here's a very simplified version:
use std::process::{Command, Stdio};
fn main() {
Command::new("bash")
.arg("-c")
.arg("uname")
.stdin(Stdio::null())
.spawn()
.unwrap()
.wait()
.unwrap();
}
On my Windows system, there are 2 bash versions:
- One provided by WSL -
C:\Windows\System32\bash.exe
- MinGW version from Git for Windows -
C:\Program Files\Git\bin\bash.exe
The PATH environment variable is configured as PATH=C:\Program Files\Git\bin\;C:\Windows\System32\;..., so the MinGW version should have precedence. And when I run the following from cmd.exe:
it produces, the expected output:
Yet, the Rust example will ignore the PATH, use the WSL instead and output:
The funny thing is that if I modify the example and just add some random environment variable:
use std::process::{Command, Stdio};
fn main() {
Command::new("bash")
.env("A", "B") // <-- This !!!!
.arg("-c")
.arg("uname")
.stdin(Stdio::null())
.spawn()
.unwrap()
.wait()
.unwrap();
}
then the Rust example will use the expected MinGW version and produce:
I have investigated a little bit and I think the problem lies in windows search path implementation
When std::process::Command::env is set, the 1. Child paths branch searches the PATH as first and it works as expected.
Otherwise, the 3 & 4. System paths part of code finds the bash executable under C:\Windows\System32 which produces the unexpected behavior.
I think we could fix this by searching 5. Parent paths before 3 & 4. System paths but I'm not sure if this change could negatively impact something else.
Tested on
rustc --version
rustc 1.76.0 (07dca489a 2024-02-04)
rustc +nightly --version
rustc 1.78.0-nightly (c67326b06 2024-03-15)
I'm building a tool which spawns a shell process. Here's a very simplified version:
On my Windows system, there are 2 bash versions:
C:\Windows\System32\bash.exeC:\Program Files\Git\bin\bash.exeThe
PATHenvironment variable is configured asPATH=C:\Program Files\Git\bin\;C:\Windows\System32\;..., so the MinGW version should have precedence. And when I run the following fromcmd.exe:it produces, the expected output:
Yet, the Rust example will ignore the
PATH, use the WSL instead and output:The funny thing is that if I modify the example and just add some random environment variable:
then the Rust example will use the expected MinGW version and produce:
I have investigated a little bit and I think the problem lies in windows search path implementation
When
std::process::Command::envis set, the1. Child pathsbranch searches thePATHas first and it works as expected.Otherwise, the
3 & 4. System pathspart of code finds thebashexecutable underC:\Windows\System32which produces the unexpected behavior.I think we could fix this by searching
5. Parent pathsbefore3 & 4. System pathsbut I'm not sure if this change could negatively impact something else.Tested on