Como executar um programa em um ambiente limpo no bash?

Respostas:

127

Você pode fazer isso com env:

env -i your_command

Ao contrário dos comentários abaixo, isso faz completamente claro o ambiente, mas não impede your_commanda criação de novas variáveis. Em particular, a execução de um shell fará com /etc/profileque ele seja executado, e o shell também poderá ter algumas configurações internas.

Você pode verificar isso com:

env -i env

ou seja, limpe o ambiente e imprima-o. A saída ficará em branco.

ams
fonte
4
Não limpa completamente o ambiente: echo 'echo $PATH' > test.sh && chmod u+x test.sh && env -i test.shimprime /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.
L0b0
2
No entanto, parece que este é o mais próximo que você pode obter - Parece que variáveis como PATH, PWDe SHLVLsão definidos automaticamente pelo Bash. +1.
L0b0 24/09/12
3
@ I0b0: Veja minha edição.
AMS
3
A variável PATH no script do primeiro comentarista não está no ambiente e, portanto, não é uma variável de ambiente. Bash aparentemente define sua própria variável shell regular, chamado PATH, se não houver uma exportados para isso: env -i bash --norc -c "declare -p PATH"declare -- PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.". Observe o "-x" para exportar (e, portanto, parte do ambiente) se você exportá-lo a si mesmo: env -i bash --norc -c "export PATH; declare -p PATH"declare -x PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
Binary Phile
34

Um bashambiente "limpo" pode ser obtido com

$ env -i bash --noprofile --norc
  • O env -icomando executa o comando fornecido na linha de comando sem transferir nenhuma das variáveis ​​de ambiente exportadas do antigo ambiente de shell para o ambiente do programa executado.

  • A --noprofileopção para bashde ler os scripts de inicialização do shell pessoais ou de todo o sistema que, de outra forma, seriam lidos para um shell de login.

  • A --norcopção para bashde ler os scripts de inicialização do shell pessoal que, de outra forma, seriam lidos para um shell interativo.

Kusalananda
fonte
Meu env não reconhece essas opções.
Paulo Carvalho
@PauloCarvalho Seu sistema não suporta env -i? Em que sistema você está?
Kusalananda
Desculpe, funciona no shell. Tentei colocá-lo em um script e, de alguma forma, gerou um erro.
Paulo Carvalho
@PauloCarvalho Desculpe, não consigo ver qual comando você digitou ou qual foi o erro que você recebeu.
Kusalananda
Ótimo - exatamente o que eu estava procurando. envpara limpar meu ambiente e --noprofileevitar o fornecimento de / etc / profile e amigos, e --norcevitar o fornecimento de ~ / .bashrc e amigos.
Felipe Alvarez
28

env -i somecommandexecuta um comando em um ambiente vazio, como ams já mencionou .

Muitos programas contam com algumas variáveis ​​de ambiente importantes, portanto, você pode mantê-las:

env -i HOME="$HOME" LC_CTYPE="${LC_ALL:-${LC_CTYPE:-$LANG}}" PATH="$PATH" USER="$USER" somecommand

Como alternativa, você pode fazer login em um pequeno ambiente de tempo de login.

ssh localhost somecommand
Gilles
fonte
1
Funciona ao executar o comando no cmdline. Como faço para colocar isso em shebang ?, parece não funcionar !
balki
Estranho, meu envnão suporta --delimitação e env -i FOO=bar -- envtenta executar um comando chamado --.
27616 Antak
@antak Isso deve ser env -i -- FOO=bar env, na verdade. Minha culpa. Não que isso --seja útil, pois o que segue não começa -.
Gilles
Não sabia que você sempre podia usar ssh no host local, isso é meio estranho. Qual é o caso de uso lá.
Edgar Aroutiounian
@EdgarAroutiounian Você pode SSH para o host local se estiver executando um servidor SSH. Por que os programadores enfrentariam o esforço de proibi-lo?
Gilles
4

Enquanto a resposta aceita estiver correta, o que você normalmente quer fazer é:

env -i bash -l -c "printenv; and any other commands"

Isso fornece um bash simples, mas funcional (o mesmo que você obteria ao fazer login no modo não interativo). Por exemplo, define o idioma, o fuso horário, HOME, etc.

Marcin Raczkowski
fonte
Isso não funciona muito bem porque env -ilimpa HOME, o que significa que bash -lnão é possível encontrar o seu .bash_profileetc. Se você deseja um shell parecido com o que você obteria em um novo login, você precisa de um indireto extra para definir HOMEprimeiro.
Elliott Slaughter
Veja esta resposta: unix.stackexchange.com/a/451389/157340
Elliott Slaughter
1

O problema com a maioria das respostas aqui é que isso env -idesaparece HOME; portanto, mesmo que você execute bash -lpor dentro, ele não lerá o seu .bash_profileetc. Se o que você procura é um shell que age como se tivesse acabado de fazer um novo login, você gostaria disso:

env -i HOME="$HOME" bash -l -c 'your_command'

Exemplo:

$ export ABC=123
$ env -i HOME="$HOME" bash -l -c 'env' | grep ABC
$ env HOME="$HOME" bash -l -c 'env' | grep ABC
ABC=123
Elliott Slaughter
fonte
1
Observe que um bashshell de login será executado .bash_loginou .bash_profile. Para obter um ambiente limpo, use --noprofileou defina HOMEum diretório que não possua esses arquivos. Suponho que depende do que você quer dizer com "limpo".
Kusalananda
1
Sim, se você quiser um shell com literalmente nada, siga a resposta original e faça env -i bash -c .... Essa resposta é específica quando você deseja um shell que parece ter acabado de fazer um novo login na máquina.
Elliott Slaughter
0

Para responder ao comentário de balki (e responder à minha própria pergunta no processo :-):

% echo Environment in calling shell: vars: $(env |wc -l); echo; ./du; echo; cat du
Environment in calling shell: vars: 43

==> This is the environment: vars: 5
PATH="$PATH"
PWD=/Users/nick
SHLVL=1
SOMETHING_TO_KEEP="$USER"
_=/usr/bin/env
==> The end.

#!/usr/bin/env -i SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh

echo "==> This is the environment: vars:" $(/usr/bin/env | /usr/bin/wc -l)
/usr/bin/env
echo "==> The end."
Coroos
fonte
Quando tento isso na minha linha shebang no CentOS 7.6, recebo este erro do env:/usr/bin/env: invalid option -- ' ' Try '/usr/bin/env --help' for more information.
ScottJ
Se eu mudar o script para usar o argumento longo --ignore-environment, recebo o seguinte:/usr/bin/env: unrecognized option '--ignore-environment SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh' Try '/usr/bin/env --help' for more information.
ScottJ