The std.env Module
The std::env module provides inspection and manipulation of the current process's execution environment, including command-line arguments, environment variables, the current working directory, executable paths, and compile-time target constants. It bridges a running Rust binary with the operating system context inherited from its parent process.
+-------------------------------------------------------------------+
| Parent Process / Shell |
| argv: ["app", "--port", "8080"] env: {"RUST_LOG": "info"} |
+-------------------------------------------------------------------+
|
v (Inherited at Process Start)
+-------------------------------------------------------------------+
| std::env Interface |
| |
| Arguments: args(), args_os() |
| Environment: var(), var_os(), vars(), vars_os() |
| unsafe { set_var(), remove_var() } (Rust 2024) |
| Directories: current_dir(), set_current_dir(), temp_dir() |
| Executable: current_exe(), split_paths(), join_paths() |
| Constants: consts::OS, consts::ARCH, consts::FAMILY |
+-------------------------------------------------------------------+
Core Functions in std::env
| Category | UTF-8 Function | OS-Native (OsString) Function |
Description |
|---|---|---|---|
| Arguments | env::args() |
env::args_os() |
Iterates over command-line arguments passed to the process. |
| Single Variable | env::var(key) |
env::var_os(key) |
Fetches the value of a single environment variable. |
| All Variables | env::vars() |
env::vars_os() |
Iterates over all (key, value) environment pairs. |
| Mutation | unsafe { env::set_var(k, v) } |
unsafe { env::set_var(k, v) } |
Sets an environment variable (unsafe in Rust 2024). |
| Removal | unsafe { env::remove_var(k) } |
unsafe { env::remove_var(k) } |
Removes an environment variable (unsafe in Rust 2024). |
| Directories | — | env::current_dir(), env::temp_dir() |
Returns PathBuf for working or temporary directory. |
| Executable | — | env::current_exe() |
Returns io::Result<PathBuf> of the running binary. |
Inspecting Runtime Context and Platform Constants
The std::env::consts submodule exposes compile-time string and character constants describing the target platform on which the binary is running.
use std::env;
fn main() {
println!("Target OS: {}", env::consts::OS);
println!("Target Family: {}", env::consts::FAMILY);
println!("Target Arch: {}", env::consts::ARCH);
println!("Exe Suffix: {:?}", env::consts::EXE_SUFFIX);
println!("DLL Extension: {:?}", env::consts::DLL_EXTENSION);
if let Ok(cwd) = env::current_dir() {
println!("Working Dir: {}", cwd.display());
}
if let Ok(exe) = env::current_exe() {
println!("Executable: {}", exe.display());
}
println!("Temp Dir: {}", env::temp_dir().display());
}
Target OS: macos
Target Family: unix
Target Arch: aarch64
Exe Suffix: ""
DLL Extension: "dylib"
Working Dir: /Users/dev/project
Executable: /Users/dev/project/target/debug/app
Temp Dir: /var/folders/xx/xxxxxxx/T/
Parsing and Joining PATH Variables
The PATH environment variable stores a list of directories separated by a platform-specific delimiter (: on Unix, ; on Windows). env::split_paths and env::join_paths parse and construct these lists portably.
use std::env;
use std::path::PathBuf;
fn main() -> Result<(), env::JoinPathsError> {
let dirs = vec![
PathBuf::from("/usr/local/bin"),
PathBuf::from("/usr/bin"),
PathBuf::from("/opt/custom/bin"),
];
// Join PathBuf items using the OS-specific delimiter
let joined = env::join_paths(&dirs)?;
println!("Joined PATH: {:?}", joined);
// Split an OsStr back into individual PathBuf items
for (idx, path) in env::split_paths(&joined).enumerate() {
println!(" [{}] {}", idx, path.display());
}
Ok(())
}
Joined PATH: "/usr/local/bin:/usr/bin:/opt/custom/bin"
[0] /usr/local/bin
[1] /usr/bin
[2] /opt/custom/bin
Thread-Safety and Rust 2024 Edition Changes
In the Rust 2024 edition, std::env::set_var and std::env::remove_var are marked unsafe. On POSIX systems (such as Linux and macOS), the underlying C library functions setenv and unsetenv mutate a global environment array without synchronization. Calling them while another thread is concurrently reading environment variables (even inside C libraries calling getenv for DNS resolution or timezone lookup) causes a data race and undefined behavior.
// ❌ does not compile
use std::env;
fn main() {
// In Rust 2024 edition, set_var is an unsafe function
env::set_var("APP_MODE", "production");
}
error[E0133]: call to unsafe function `std::env::set_var` is unsafe and requires unsafe function or block
--> src/main.rs:5:5
|
5 | env::set_var("APP_MODE", "production");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function
|
= note: consult the function's documentation for information on how to avoid undefined behavior
To pass environment variables to child processes safely without mutating global state, configure them directly on std::process::Command::env rather than calling env::set_var.