std::process::Command sometimes ignores PATH env variable on Windows
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
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:
bash -c uname
it produces, the expected output:
MINGW64_NT-10.0-19045
Yet, the Rust example will ignore the PATH, use the WSL instead and output:
Linux
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:
MINGW64_NT-10.0-19045
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)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with library/std/src/sys/pal/windows/process.rs, especially the Windows search-path branches described in the issue, and reproduce the minimal std::process::Command example on Windows with and without Command::env. Compare the selected executable against the configured PATH precedence and assess the effect of changing the search order. Done means the behavior is consistent with PATH without breaking the other documented search cases.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100