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.


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.


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

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.


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


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

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."

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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.