---
title: "Módulo std::env em Rust"
url: "https://rustlang.com.br/stdlib/env-module/"
markdown_url: "https://rustlang.com.br/stdlib/env-module.MD"
description: "Referência completa do módulo std::env em Rust: var, set_var, args, current_dir, current_exe, temp_dir e constantes OS e ARCH com exemplos."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Módulo std::env em Rust

Referência completa do módulo std::env em Rust: var, set_var, args, current_dir, current_exe, temp_dir e constantes OS e ARCH com exemplos.


# Módulo std::env em Rust

O módulo `std::env` fornece funções para interagir com o ambiente de execução do processo: variáveis de ambiente, argumentos da linha de comando, diretório de trabalho atual, caminho do executável, diretório temporário e constantes sobre a plataforma (sistema operacional, arquitetura). É essencial para programas CLI, configuração por ambiente e código cross-platform.

## Visão geral e tipos-chave

### Variáveis de ambiente

- **`env::var(key)`** — lê uma variável de ambiente como `Result<String, VarError>`
- **`env::var_os(key)`** — lê como `Option<OsString>` (não falha em Unicode inválido)
- **`env::set_var(key, value)`** — define uma variável de ambiente
- **`env::remove_var(key)`** — remove uma variável de ambiente
- **`env::vars()`** — iterador sobre todas as variáveis como `(String, String)`
- **`env::vars_os()`** — iterador sobre todas como `(OsString, OsString)`

### Argumentos e caminhos

- **`env::args()`** — iterador sobre argumentos CLI como `String`
- **`env::args_os()`** — iterador sobre argumentos como `OsString`
- **`env::current_dir()`** — diretório de trabalho atual
- **`env::set_current_dir(path)`** — altera o diretório de trabalho
- **`env::current_exe()`** — caminho do executável atual
- **`env::temp_dir()`** — diretório temporário do sistema

### Constantes da plataforma (env::consts)

- **`consts::OS`** — sistema operacional (`"linux"`, `"windows"`, `"macos"`)
- **`consts::ARCH`** — arquitetura (`"x86_64"`, `"aarch64"`, `"arm"`)
- **`consts::FAMILY`** — família do SO (`"unix"`, `"windows"`)
- **`consts::EXE_SUFFIX`** — sufixo de executáveis (`""` no Unix, `".exe"` no Windows)
- **`consts::DLL_SUFFIX`** — sufixo de bibliotecas dinâmicas (`.so`, `.dll`, `.dylib`)

## Padrões comuns com código

### Ler variáveis de ambiente com fallback

```rust
use std::env;

fn configuracao() -> (String, u16, String) {
    let host = env::var("APP_HOST").unwrap_or_else(|_| "127.0.0.1".to_string());
    let porta: u16 = env::var("APP_PORT")
        .ok()
        .and_then(|v| v.parse().ok())
        .unwrap_or(8080);
    let modo = env::var("APP_MODE").unwrap_or_else(|_| "development".to_string());

    (host, porta, modo)
}

fn main() {
    let (host, porta, modo) = configuracao();
    println!("Servidor: {}:{} (modo: {})", host, porta, modo);
}
```

### Processar argumentos da linha de comando

```rust
use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();

    // args[0] é o nome do programa
    println!("Programa: {}", args[0]);
    println!("Argumentos: {:?}", &args[1..]);

    if args.len() < 2 {
        eprintln!("Uso: {} <comando> [opcoes]", args[0]);
        eprintln!("Comandos: listar, criar, remover");
        std::process::exit(1);
    }

    match args[1].as_str() {
        "listar" => println!("Listando itens..."),
        "criar" => {
            let nome = args.get(2).map(|s| s.as_str()).unwrap_or("sem_nome");
            println!("Criando: {}", nome);
        }
        "remover" => {
            let nome = args.get(2).map(|s| s.as_str()).unwrap_or("");
            if nome.is_empty() {
                eprintln!("Erro: especifique o nome para remover");
                std::process::exit(1);
            }
            println!("Removendo: {}", nome);
        }
        cmd => {
            eprintln!("Comando desconhecido: '{}'", cmd);
            std::process::exit(1);
        }
    }
}
```

### Informações da plataforma

```rust
use std::env;

fn info_plataforma() {
    println!("=== Informações da Plataforma ===");
    println!("SO:            {}", env::consts::OS);
    println!("Arquitetura:   {}", env::consts::ARCH);
    println!("Família:       {}", env::consts::FAMILY);
    println!("Sufixo EXE:    '{}'", env::consts::EXE_SUFFIX);
    println!("Sufixo DLL:    '{}'", env::consts::DLL_SUFFIX);
    println!("Prefixo DLL:   '{}'", env::consts::DLL_PREFIX);

    println!("\n=== Caminhos ===");
    match env::current_dir() {
        Ok(dir) => println!("Dir atual:     {}", dir.display()),
        Err(e) => println!("Dir atual:     erro: {}", e),
    }
    match env::current_exe() {
        Ok(exe) => println!("Executável:    {}", exe.display()),
        Err(e) => println!("Executável:    erro: {}", e),
    }
    println!("Dir temp:      {}", env::temp_dir().display());
}

fn main() {
    info_plataforma();
}
```

## Tabela de funções e constantes

### Funções de variáveis de ambiente

| Função | Retorno | Descrição |
|---|---|---|
| `env::var(key)` | `Result<String, VarError>` | Lê variável como String UTF-8 |
| `env::var_os(key)` | `Option<OsString>` | Lê variável como OsString |
| `env::set_var(key, value)` | `()` | Define variável de ambiente |
| `env::remove_var(key)` | `()` | Remove variável de ambiente |
| `env::vars()` | `Vars` | Iterador `(String, String)` |
| `env::vars_os()` | `VarsOs` | Iterador `(OsString, OsString)` |

### Funções de argumentos e caminhos

| Função | Retorno | Descrição |
|---|---|---|
| `env::args()` | `Args` | Iterador sobre argumentos CLI (String) |
| `env::args_os()` | `ArgsOs` | Iterador sobre argumentos CLI (OsString) |
| `env::current_dir()` | `io::Result<PathBuf>` | Diretório de trabalho atual |
| `env::set_current_dir(path)` | `io::Result<()>` | Altera diretório de trabalho |
| `env::current_exe()` | `io::Result<PathBuf>` | Caminho do executável |
| `env::temp_dir()` | `PathBuf` | Diretório temporário do sistema |

### Constantes (env::consts)

| Constante | Tipo | Exemplos |
|---|---|---|
| `consts::OS` | `&str` | `"linux"`, `"windows"`, `"macos"` |
| `consts::ARCH` | `&str` | `"x86_64"`, `"aarch64"`, `"arm"` |
| `consts::FAMILY` | `&str` | `"unix"`, `"windows"` |
| `consts::EXE_SUFFIX` | `&str` | `""` (Unix), `".exe"` (Windows) |
| `consts::EXE_EXTENSION` | `&str` | `""` (Unix), `"exe"` (Windows) |
| `consts::DLL_PREFIX` | `&str` | `"lib"` (Unix), `""` (Windows) |
| `consts::DLL_SUFFIX` | `&str` | `".so"` (Linux), `".dll"` (Win), `".dylib"` (macOS) |
| `consts::DLL_EXTENSION` | `&str` | `"so"`, `"dll"`, `"dylib"` |

## Exemplos práticos

### Exemplo 1: Configuração por ambiente com validação

```rust
use std::env;
use std::net::SocketAddr;

#[derive(Debug)]
struct Config {
    endereco: SocketAddr,
    database_url: String,
    nivel_log: String,
    max_conexoes: usize,
    modo_debug: bool,
}

impl Config {
    fn do_ambiente() -> Result<Self, String> {
        let host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());
        let porta = env::var("PORT")
            .unwrap_or_else(|_| "3000".to_string())
            .parse::<u16>()
            .map_err(|e| format!("PORT inválida: {}", e))?;

        let endereco: SocketAddr = format!("{}:{}", host, porta)
            .parse()
            .map_err(|e| format!("Endereço inválido: {}", e))?;

        let database_url = env::var("DATABASE_URL")
            .map_err(|_| "DATABASE_URL é obrigatória".to_string())?;

        let nivel_log = env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string());
        let validos = ["trace", "debug", "info", "warn", "error"];
        if !validos.contains(&nivel_log.as_str()) {
            return Err(format!(
                "LOG_LEVEL inválido: '{}'. Use: {:?}",
                nivel_log, validos
            ));
        }

        let max_conexoes = env::var("MAX_CONN")
            .ok()
            .and_then(|v| v.parse().ok())
            .unwrap_or(100);

        let modo_debug = env::var("DEBUG")
            .map(|v| v == "1" || v.to_lowercase() == "true")
            .unwrap_or(false);

        Ok(Config {
            endereco,
            database_url,
            nivel_log,
            max_conexoes,
            modo_debug,
        })
    }
}

fn main() {
    match Config::do_ambiente() {
        Ok(config) => {
            println!("Configuração carregada:");
            println!("  Endereço:     {}", config.endereco);
            println!("  Database:     {}", config.database_url);
            println!("  Log:          {}", config.nivel_log);
            println!("  Max conexões: {}", config.max_conexoes);
            println!("  Debug:        {}", config.modo_debug);
        }
        Err(e) => {
            eprintln!("Erro na configuração: {}", e);
            eprintln!("\nVariáveis esperadas:");
            eprintln!("  DATABASE_URL  (obrigatória)");
            eprintln!("  HOST          (padrão: 0.0.0.0)");
            eprintln!("  PORT          (padrão: 3000)");
            eprintln!("  LOG_LEVEL     (padrão: info)");
            eprintln!("  MAX_CONN      (padrão: 100)");
            eprintln!("  DEBUG         (padrão: false)");
            std::process::exit(1);
        }
    }
}
```

### Exemplo 2: Parser de argumentos CLI manual

```rust
use std::env;
use std::collections::HashMap;

#[derive(Debug)]
struct ArgsParser {
    programa: String,
    comando: Option<String>,
    flags: HashMap<String, Option<String>>,
    posicionais: Vec<String>,
}

impl ArgsParser {
    fn parse() -> Self {
        let mut args = env::args();
        let programa = args.next().unwrap_or_default();

        let mut comando = None;
        let mut flags = HashMap::new();
        let mut posicionais = Vec::new();

        let args_restantes: Vec<String> = args.collect();
        let mut i = 0;

        while i < args_restantes.len() {
            let arg = &args_restantes[i];

            if arg.starts_with("--") {
                let chave = arg.trim_start_matches("--").to_string();
                if let Some((k, v)) = chave.split_once('=') {
                    flags.insert(k.to_string(), Some(v.to_string()));
                } else if i + 1 < args_restantes.len() && !args_restantes[i + 1].starts_with('-') {
                    flags.insert(chave, Some(args_restantes[i + 1].clone()));
                    i += 1;
                } else {
                    flags.insert(chave, None);
                }
            } else if arg.starts_with('-') {
                let chave = arg.trim_start_matches('-').to_string();
                flags.insert(chave, None);
            } else if comando.is_none() {
                comando = Some(arg.clone());
            } else {
                posicionais.push(arg.clone());
            }

            i += 1;
        }

        ArgsParser {
            programa,
            comando,
            flags,
            posicionais,
        }
    }

    fn tem_flag(&self, nome: &str) -> bool {
        self.flags.contains_key(nome)
    }

    fn valor_flag(&self, nome: &str) -> Option<&str> {
        self.flags.get(nome).and_then(|v| v.as_deref())
    }
}

fn main() {
    let args = ArgsParser::parse();
    println!("Programa: {}", args.programa);
    println!("Comando: {:?}", args.comando);
    println!("Flags: {:?}", args.flags);
    println!("Posicionais: {:?}", args.posicionais);

    // Uso: meu_app build --release --target x86_64 arquivo.rs
    if args.tem_flag("help") || args.tem_flag("h") {
        println!("\nUso: {} <comando> [opcoes] [arquivos...]", args.programa);
        println!("Comandos: build, test, run");
        println!("Opções: --release, --target <alvo>, --verbose, -h/--help");
    }

    if let Some(alvo) = args.valor_flag("target") {
        println!("Compilando para: {}", alvo);
    }
}
```

### Exemplo 3: Listar e filtrar variáveis de ambiente

```rust
use std::env;

fn listar_variaveis(filtro: Option<&str>) {
    let mut vars: Vec<(String, String)> = env::vars().collect();
    vars.sort_by(|a, b| a.0.cmp(&b.0));

    let filtradas: Vec<&(String, String)> = match filtro {
        Some(f) => vars.iter().filter(|(k, _)| {
            k.to_lowercase().contains(&f.to_lowercase())
        }).collect(),
        None => vars.iter().collect(),
    };

    println!("Variáveis de ambiente ({} encontradas):", filtradas.len());
    for (chave, valor) in &filtradas {
        let valor_exib = if valor.len() > 80 {
            format!("{}...", &valor[..77])
        } else {
            valor.clone()
        };
        println!("  {}={}", chave, valor_exib);
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();
    let filtro = args.get(1).map(|s| s.as_str());
    listar_variaveis(filtro);
}
```

### Exemplo 4: Código cross-platform com consts

```rust
use std::env;
use std::path::PathBuf;

fn diretorio_dados() -> PathBuf {
    match env::consts::OS {
        "linux" => {
            env::var("XDG_DATA_HOME")
                .map(PathBuf::from)
                .unwrap_or_else(|_| {
                    let home = env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
                    PathBuf::from(home).join(".local/share")
                })
                .join("meu_app")
        }
        "macos" => {
            let home = env::var("HOME").unwrap_or_else(|_| "/tmp".to_string());
            PathBuf::from(home)
                .join("Library/Application Support/MeuApp")
        }
        "windows" => {
            env::var("LOCALAPPDATA")
                .map(PathBuf::from)
                .unwrap_or_else(|_| PathBuf::from("C:\\ProgramData"))
                .join("MeuApp")
        }
        _ => env::temp_dir().join("meu_app"),
    }
}

fn nome_executavel(nome_base: &str) -> String {
    format!("{}{}", nome_base, env::consts::EXE_SUFFIX)
}

fn nome_biblioteca(nome_base: &str) -> String {
    format!(
        "{}{}{}",
        env::consts::DLL_PREFIX,
        nome_base,
        env::consts::DLL_SUFFIX
    )
}

fn main() {
    println!("Diretório de dados: {}", diretorio_dados().display());
    println!("Executável: {}", nome_executavel("meu_app"));
    println!("Biblioteca: {}", nome_biblioteca("utils"));

    // Condicionais em tempo de compilação vs. runtime
    // cfg!() é em tempo de compilação (preferível quando possível)
    if cfg!(target_os = "linux") {
        println!("Compilado para Linux");
    }

    // env::consts é em runtime (útil para lógica dinâmica)
    match env::consts::ARCH {
        "x86_64" => println!("Rodando em 64-bit x86"),
        "aarch64" => println!("Rodando em ARM 64-bit"),
        arch => println!("Rodando em: {}", arch),
    }
}
```

### Exemplo 5: Gerenciar arquivos temporários

```rust
use std::env;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;

struct ArquivoTemporario {
    caminho: PathBuf,
}

impl ArquivoTemporario {
    fn novo(prefixo: &str, extensao: &str) -> io::Result<Self> {
        let dir = env::temp_dir();
        let id: u64 = std::time::SystemTime::now()
            .duration_since(std::time::UNIX_EPOCH)
            .unwrap()
            .as_nanos() as u64;

        let nome = format!("{}_{}.{}", prefixo, id, extensao);
        let caminho = dir.join(nome);

        // Criar o arquivo vazio
        fs::File::create(&caminho)?;

        Ok(ArquivoTemporario { caminho })
    }

    fn caminho(&self) -> &std::path::Path {
        &self.caminho
    }

    fn escrever(&self, conteudo: &str) -> io::Result<()> {
        fs::write(&self.caminho, conteudo)
    }

    fn ler(&self) -> io::Result<String> {
        fs::read_to_string(&self.caminho)
    }
}

impl Drop for ArquivoTemporario {
    fn drop(&mut self) {
        if self.caminho.exists() {
            let _ = fs::remove_file(&self.caminho);
        }
    }
}

fn main() -> io::Result<()> {
    println!("Diretório temporário: {}", env::temp_dir().display());

    let temp = ArquivoTemporario::novo("relatorio", "txt")?;
    println!("Arquivo temp: {}", temp.caminho().display());

    temp.escrever("Dados temporários do processamento\nLinha 2\n")?;
    let conteudo = temp.ler()?;
    println!("Conteúdo: {}", conteudo);

    // Arquivo é removido automaticamente quando temp sai de escopo
    println!("Arquivo será limpo automaticamente");
    Ok(())
}
```

## Padrões de tratamento de erro para I/O

### VarError: variável não definida vs. Unicode inválido

```rust
use std::env;

fn ler_var_obrigatoria(nome: &str) -> Result<String, String> {
    match env::var(nome) {
        Ok(valor) => {
            if valor.trim().is_empty() {
                Err(format!("'{}' está definida mas vazia", nome))
            } else {
                Ok(valor)
            }
        }
        Err(env::VarError::NotPresent) => {
            Err(format!("'{}' não está definida", nome))
        }
        Err(env::VarError::NotUnicode(valor)) => {
            // Tentar usar a versão lossy
            eprintln!(
                "Aviso: '{}' contém caracteres não-Unicode: {:?}",
                nome, valor
            );
            Ok(valor.to_string_lossy().to_string())
        }
    }
}

fn main() {
    let variaveis = ["DATABASE_URL", "API_KEY", "HOME", "INEXISTENTE"];
    for var in &variaveis {
        match ler_var_obrigatoria(var) {
            Ok(v) => println!("{} = {}", var, v),
            Err(e) => eprintln!("{}: {}", var, e),
        }
    }
}
```

### Cuidado com set_var e segurança entre threads

```rust
use std::env;

fn main() {
    // AVISO: set_var NÃO é thread-safe no Rust!
    // Use apenas na inicialização, antes de criar threads.

    // Definir variáveis na inicialização
    if env::var("RUST_LOG").is_err() {
        // Seguro: estamos na thread principal, antes de qualquer spawn
        unsafe {
            env::set_var("RUST_LOG", "info");
        }
    }

    // Para configuração em tempo de execução, use tipos thread-safe
    // como Arc<RwLock<HashMap<String, String>>> em vez de env vars.
}
```

## Dicas de desempenho

- **Cache variáveis de ambiente** que serão lidas frequentemente. Cada chamada a `env::var()` faz uma syscall.
- **Use `env::args_os()`** se precisar processar argumentos que podem conter caracteres não-UTF-8 (ex: nomes de arquivo em sistemas com locales exóticos).
- **Prefira `cfg!()`** a `env::consts::OS` para decisões que podem ser resolvidas em tempo de compilação — o compilador otimiza o branch morto.
- **Colete `args()` em `Vec`** apenas uma vez se precisar acessar os argumentos múltiplas vezes.

## Veja também

- [Módulo std::process](/stdlib/process-module/) — executar comandos e controlar processos
- [Path e PathBuf](/stdlib/path/) — manipulação de caminhos retornados por env
- [Módulo std::fs](/stdlib/fs-module/) — operações de filesystem
- [stdin, stdout e stderr](/stdlib/stdin-stdout/) — I/O padrão combinado com args
- [Variáveis de Ambiente](/receitas/variaveis-ambiente/) — receita prática de variáveis de ambiente
- [Ler Argumentos CLI](/receitas/ler-argumentos-cli/) — receita prática de argumentos
- Documentação oficial: [`std::env`](https://doc.rust-lang.org/std/env/)
