Env::var not reading env variable on powershell and cmd only

So, I'm on windows 10 and I've been trying to code an app which will read a config on $HOME/.myapp

I have a vague recollection of using this before and with no issues but now env::var doesn't look like it can read HOME from powershell and cmd however it works fine on MINGW64 or wsl terminal.

I've written a very simple app using the env::var example from their docs:

#![allow(unused)]
fn main() {
    use std::env;

    let key = "HOME";
    match env::var(key) {
        Ok(val) => println!("{}: {:?}", key, val),
        Err(e) => println!("couldn't interpret {}: {}", key, e),
    }
}

If I run it on MINGW64 or WSL terminal it returns the content of the variable HOME.

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.02s
     Running `target\debug\test-env.exe`
Content of HOME env variable: C:\Users\my.user

WSL returns /home/user

However, if I try on powershell or cmd I get this error

PS C:\source\__github\rust\test-env> cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `target\debug\test-env.exe`
couldn't interpret HOME: environment variable not found

If in powershell for example I just type $HOME it prints the value of HOME.

PS C:\source\__github\rust\test-env> $HOME
C:\Users\my.user

This is my rustup --version:

rustup 1.24.3 (ce5817a94 2021-05-31)
info: This is the version for the rustup toolchain manager, not the rustc compiler.
info: The currently active `rustc` version is `rustc 1.54.0 (a178d0322 2021-07-26)`

Am I missing something?

HOME isn't a normal environment variable set under the native windows environment, although it still may be set in certain circumstances. I believe USERPROFILE is the closest equivalent.

You may want to use an existing crate to achieve the functionality you are looking for, such as dirs-next or directories-next

4 Likes

$HOME is a powershell variable and not an environment variable. Environment variables are prefixed with $env: (e.g. $env:USERPROFILE).

You can try to be cross-platform with:

match env::var("HOME").or_else(|| env::var("USERPROFILE")) {
    Ok(val) => println!("Home directory: {}", val),
    Err(_) => println!("Couldn't read home directory"),
}

There's a crate for that:

Note that this gets the user's profile folder. Which may not be where the user wants you to dump your configuration, etc. If you do use this then at least do what cargo and rustup does and add another environment variable so that users can set it to the right directory for the platform.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.