Comando env: Executando Comandos com Ambiente Modificado
O Que e o Comando env?
Conclusao:
enve 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 funcoes principais:
- Definir variaveis de ambiente temporariamente e executar um comando (
env LANG=C datealtera uma variavel para aquela unica invocacao) - Listar o ambiente atual quando executado sem argumentos (mesmo que
printenv)
Tambem e 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 / distribuicoes baseadas em RHEL e outras distribuicoes Linux comuns) - Algumas opcoes (
-C/-S) dependem da versao do coreutils. Veja abaixo.
Por Que Usar env VAR=valor?
Conclusao: Porque voce quer que uma variavel se aplique a apenas um comando, sem torna-la permanente e sem poluir o shell atual.
exportpersiste;enve de uso unico.
Existem varias maneiras de executar um comando com uma variavel alterada. Conheca as diferencas.
# (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 variavel apenas para aquela unica invocacao. A forma (3), export, mantem a alteracao para todos os comandos executados depois. Quando voce quer "apenas desta vez" ou "nao deixar a configuracao para tras", escolha (1) ou (2).
Como (1) e (2) diferem
LANG=C datee sintaxe do shell (uma atribuicao prefixada). O shell a interpreta.env LANG=C datelanca o executavelenvseparado, que constroi o ambiente em um processo filho e entao executadateviaexec.
Para uso interativo o resultado e o mesmo. env se torna necessario quando nao ha shell envolvido: linhas shebang, argumentos para APIs da familia exec, ou quando se parte de um ambiente vazio.
Definir uma Variavel Temporariamente e Executar
Conclusao: Escreva
env NOME=valor comando args.... Liste multiplas variaveis separadas por espacos.
# 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 varias variaveis de uma vez, liste-as em sequencia:
$ env LANG=C LC_ALL=C TZ=UTC ./myscript.sh
Isolando erros relacionados ao locale
Em um ambiente nao-ingles, mensagens de erro podem ser traduzidas e dificeis de pesquisar. Fixar mensagens em ingles com env LANG=C comando facilita a busca e o registro de problemas.
Executar com Ambiente Vazio (env -i)
Conclusao:
env -iinicia o comando com todas as variaveis de ambiente herdadas removidas. E ideal para isolar problemas do tipo "funciona so na minha maquina".
# Verificar o que resta (quase nada) $ env -i env
Com -i (--ignore-environment), ate o PATH nao e herdado. Entao sob -i voce deve especificar o comando pelo caminho absoluto ou passar as variaveis necessarias explicitamente.
# PATH foi removido, entao passe apenas as variaveis necessarias $ env -i PATH=/usr/bin:/bin LANG=C ./myscript.sh
Sob env -i, variaveis como HOME, PATH e LANG ficam indefinidas. Se um script depende delas, pode se comportar de forma inesperada. Passar apenas as variaveis realmente necessarias e o padrao seguro.
Executar sem uma Variavel Especifica (env -u)
Conclusao:
env -u NOMEremove apenas aquela variavel antes de executar o comando. Diferente de-i, que limpa tudo, use para desabilitar uma unica variavel.
# 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 variavel. Permite testar a hipotese "talvez esta variavel seja a culpada" sem editar nenhum arquivo de configuracao.
Executar em um Diretorio Diferente (env -C)
Conclusao:
env -C DIR comandomuda para o diretorio indicado antes de executar o comando. Compactacd DIR && comandoem uma linha sem subshell.
$ env -C /var/log tail -n 20 syslog
-C (--chdir) esta disponivel no coreutils 8.28 e posterior. Nao esta disponivel em ambientes mais antigos. Verifique com env --version (veja abaixo).
Usando /usr/bin/env no Shebang
Conclusao: Um shebang como
#!/usr/bin/env python3encontra o interpretador atraves doPATH. Evita codificar um caminho absoluto do interpretador, tornando o script portavel.
#!/usr/bin/env python3
print("hello")Escrever #!/usr/bin/python3 diretamente falha em sistemas onde o Python esta em outro lugar (/usr/local/bin, um virtualenv, etc.). #!/usr/bin/env python3 busca no PATH, usando o primeiro python3 encontrado no ambiente do usuario.
#!/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 multiplos argumentos.
-S requer coreutils 8.30 ou posterior. O suporte tambem difere no macOS (BSD env), entao verifique o ambiente alvo antes de usa-lo em scripts distribuidos.
env vs printenv vs set
Conclusao:
envsem argumentos lista apenas variaveis de ambiente. Usesetpara todas as variaveis incluindo as do shell, eprintenv NOMEpara uma unica.
| Objetivo | Comando |
|---|---|
| Listar variaveis de ambiente | env ou printenv |
| Mostrar uma variavel de ambiente | printenv PATH (env sozinho nao filtra) |
| Incluir variaveis do shell tambem | set (builtin do bash) |
| Definir temporariamente e executar | env VAR=val cmd |
Passar um unico argumento como env PATH nao 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".
Resolucao de Problemas
Conclusao: Os tropecos comuns com
envsao "sem PATH apos-i" e "-C/-Sindisponivel em sistema antigo." Uma verificacao de versao resolve a maioria deles.
"env: '...': No such file or directory"
env trata o primeiro argumento sem = como um nome de comando. Voce 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 nao encontrado apos env -i
-i tambem limpa o PATH. Especifique o PATH explicitamente como em env -i PATH=/usr/bin:/bin comando, ou forneca 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