args, vars, current_dir

`std::env::args()` returns an iterator of program arguments, with the executable path as the first item. `std::env::vars()` iterates over the current environment as `(String, String)` pairs. `std::env::current_dir()` returns the working directory as a `PathBuf`. All three are synchronous and cheap.

Setting and removing variables

`std::env::set_var` and `std::env::remove_var` mutate the process environment. They are not thread-safe in general because the underlying POSIX APIs (`setenv`, `unsetenv`) are not atomic with `getenv`. Set environment variables before spawning threads, or use a process-global `Mutex` to serialise mutations.

For deeper background, see a complete cheat-sheet of std collection complexities for the broader context behind this section.

Path and search paths

`std::env::current_exe()` returns the path of the running binary. `std::env::join_paths` and `std::env::split_paths` handle the platform-specific PATH separator (`:` on Unix, `;` on Windows). Use them whenever you read or build an OS PATH-like variable.

Build-time vs runtime

`env::var("FOO")` reads the variable at runtime. The `env!("FOO")` macro reads it at compile time and bakes it into the binary — useful for embedding the build commit, build timestamp, or feature flags. The `option_env!` variant returns `Option<&'static str>` if you want a graceful fallback.

For deeper background, see the official Rust API guidelines for module-level design for the broader context behind this section.

Common pitfalls

`args()` panics if any argument is not valid Unicode; for binary-safe argument access on Unix use `std::env::args_os()` and `OsString`. Likewise `vars` has a `vars_os` counterpart. Always reach for the OS variant if you might encounter non-UTF-8 environments (legacy Windows code pages, embedded shells).