rust-lang / rust-lang/rust

std::process::Command sometimes ignores PATH env variable on Windows

Open
#122,660 11 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

C-bug O-windows T-libs
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.