Comando env: Executando Comandos com Ambiente Modificado
O Que é o Comando env?
Conclusão:
envé uma ferramenta do coreutils que executa um comando com ambiente modificado. Escrito comoenv VAR=valor comando, permite executar um comando em um ambiente diferente sem poluir o shell atual.
env tem duas funções principais:
- Definir variáveis de ambiente temporariamente e executar um comando (
env LANG=C datealtera uma variável para aquela única invocação) - Listar o ambiente atual quando executado sem argumentos (mesmo que
printenv)
Também é amplamente usado na linha shebang de scripts (#!/usr/bin/env python3) para localizar um interpretador via PATH.
Ambiente para este artigo
- GNU coreutils
env(Ubuntu / Debian / distribuições baseadas em RHEL e outras distribuições Linux comuns) - Algumas opções (
-C/-S) dependem da versão do coreutils. Veja abaixo.
Por Que Usar env VAR=valor?
Conclusão: Porque você quer que uma variável se aplique a apenas um comando, sem torná-la permanente e sem poluir o shell atual.
exportpersiste;envé de uso único.
Existem várias maneiras de executar um comando com uma variável alterada. Conheça as diferenças.
# (1) Atribuicao temporaria do shell (sem env) $ LANG=C date # (2) Atribuicao temporaria via env $ env LANG=C date # (3) export (afeta todos os comandos posteriores, persistente) $ export LANG=C $ date
As formas (1) e (2) alteram a variável apenas para aquela única invocação. A forma (3), export, mantém a alteração para todos os comandos executados depois. Quando você quer "apenas desta vez" ou "não deixar a configuração para trás", escolha (1) ou (2).
Como (1) e (2) diferem
LANG=C dateé sintaxe do shell (uma atribuição prefixada). O shell a interpreta.env LANG=C datelanca o executávelenvseparado, que constrói o ambiente em um processo filho e então executadateviaexec.
Para uso interativo o resultado é o mesmo. env se torna necessário quando não há shell envolvido: linhas shebang, argumentos para APIs da família exec, ou quando se parte de um ambiente vazio.
Definir uma Variável Temporariamente e Executar
Conclusão: Escreva
env NOME=valor comando args.... Liste múltiplas variáveis separadas por espaços.
# Mostrar a data com o fuso horario temporariamente definido como UTC $ env TZ=UTC date # Forcar o locale C para obter mensagens em ingles (util para investigacao de logs) $ env LANG=C ls /nonexistent
ls: cannot access '/nonexistent': No such file or directory
Para definir várias variáveis de uma vez, liste-as em sequência:
$ env LANG=C LC_ALL=C TZ=UTC ./myscript.sh
Isolando erros relacionados ao locale
Em um ambiente não-inglês, mensagens de erro podem ser traduzidas e difíceis de pesquisar. Fixar mensagens em inglês com env LANG=C comando facilita a busca e o registro de problemas.
Executar com Ambiente Vazio (env -i)
Conclusão:
env -iinicia o comando com todas as variáveis de ambiente herdadas removidas. É ideal para isolar problemas do tipo "funciona só na minha máquina".
# Verificar o que resta (quase nada) $ env -i env
Com -i (--ignore-environment), até o PATH não é herdado. Então sob -i você deve especificar o comando pelo caminho absoluto ou passar as variáveis necessárias explicitamente.
# PATH foi removido, entao passe apenas as variaveis necessarias $ env -i PATH=/usr/bin:/bin LANG=C ./myscript.sh
Sob env -i, variáveis como HOME, PATH e LANG ficam indefinidas. Se um script depende delas, pode se comportar de forma inesperada. Passar apenas as variáveis realmente necessárias é o padrão seguro.
Executar sem uma Variável Específica (env -u)
Conclusão:
env -u NOMEremove apenas aquela variável antes de executar o comando. Diferente de-i, que limpa tudo, use para desabilitar uma única variável.
# Desabilitar temporariamente configuracoes de proxy e testar a conexao $ env -u http_proxy -u https_proxy curl https://example.com
-u (--unset) pode ser repetido para cada variável. Permite testar a hipotese "talvez esta variável seja a culpada" sem editar nenhum arquivo de configuração.
Executar em um Diretório Diferente (env -C)
Conclusão:
env -C DIR comandomuda para o diretório indicado antes de executar o comando. Compactacd DIR && comandoem uma linha sem subshell.
$ env -C /var/log tail -n 20 syslog
-C (--chdir) está disponível no coreutils 8.28 e posterior. Não está disponível em ambientes mais antigos. Verifique com env --version (veja abaixo).
Usando /usr/bin/env no Shebang
Conclusão: Um shebang como
#!/usr/bin/env python3encontra o interpretador através doPATH. Evita codificar um caminho absoluto do interpretador, tornando o script portável.
#!/usr/bin/env python3
print("hello")Escrever #!/usr/bin/python3 diretamente falha em sistemas onde o Python está em outro lugar (/usr/local/bin, um virtualenv, etc.). #!/usr/bin/env python3 busca no PATH, usando o primeiro python3 encontrado no ambiente do usuário.
#!/usr/bin/env -S python3 -u
Para passar argumentos ao interpretador em uma linha shebang, use -S (--split-string). Um shebang normalmente permite apenas um argumento; -S divide a string em múltiplos argumentos.
-S requer coreutils 8.30 ou posterior. O suporte também difere no macOS (BSD env), então verifique o ambiente alvo antes de usá-lo em scripts distribuídos.
env vs printenv vs set
Conclusão:
envsem argumentos lista apenas variáveis de ambiente. Usesetpara todas as variáveis incluindo as do shell, eprintenv NOMEpara uma única.
| Objetivo | Comando |
|---|---|
| Listar variáveis de ambiente | env ou printenv |
| Mostrar uma variável de ambiente | printenv PATH (env sozinho não filtra) |
| Incluir variáveis do shell também | set (builtin do bash) |
| Definir temporariamente e executar | env VAR=val cmd |
Passar um único argumento como env PATH não imprime o valor: env o trata como um nome de comando e reporta "No such file or directory." Para ver apenas o valor, use printenv PATH ou echo "$PATH".
Resolução de Problemas
Conclusão: Os tropeços comuns com
envsão "sem PATH após-i" e "-C/-Sindisponível em sistema antigo." Uma verificação de versão resolve a maioria deles.
"env: '...': No such file or directory"
env trata o primeiro argumento sem = como um nome de comando. Você recebe este erro de env LANG C date (falta um =) ou env PATH (tentando ler um valor). Certifique-se de que a forma seja NOME=valor.
Comando não encontrado após env -i
-i também limpa o PATH. Especifique o PATH explicitamente como em env -i PATH=/usr/bin:/bin comando, ou forneça o comando pelo caminho absoluto.
# Verificar a versao do env (para decidir se -C / -S estao disponiveis) $ env --version | head -1
env (GNU coreutils) 9.4