¿Cómo ejecutar un programa en un entorno limpio en bash?

Respuestas:

127

Puedes hacer esto con env:

env -i your_command

Contrariamente a los comentarios de abajo, esto lo hace completamente claro el medio ambiente, pero no impide your_commandel establecimiento de nuevas variables. En particular, ejecutar un shell hará /etc/profileque se ejecute, y el shell también puede tener algunas configuraciones integradas.

Puede verificar esto con:

env -i env

es decir, limpie el entorno y luego imprímalo. La salida estará en blanco.

ams
fuente
44
No elimina completamente el entorno: echo 'echo $PATH' > test.sh && chmod u+x test.sh && env -i test.shimpresiones /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin.
l0b0
2
Sin embargo, parece que esto es lo más cerca que puede conseguir - Parece que variables como PATH, PWDy SHLVLse ajustan automáticamente por Bash. +1.
l0b0
3
@ I0b0: Vea mi edición.
enms.
3
La variable PATH en el script del primer comentarista no está en el entorno y, por lo tanto, no es una variable de entorno. Aparentemente, Bash establece su propia variable de shell regular llamada PATH si no se exporta una: env -i bash --norc -c "declare -p PATH"da declare -- PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:.". Tenga en cuenta el "-x" para exportado (y, por lo tanto, parte del entorno) si lo exporta usted mismo: env -i bash --norc -c "export PATH; declare -p PATH"dadeclare -x PATH="/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/bin:/sbin:."
Binary Phile
34

Se bashpuede tener un ambiente "limpio" con

$ env -i bash --noprofile --norc
  • El env -icomando ejecuta el comando que se le da en la línea de comando sin transferir ninguna de las variables de entorno exportadas del antiguo entorno de shell al entorno del programa ejecutado.

  • La --noprofileopción deja bashde leer los scripts de inicialización del shell personal o de todo el sistema que de otro modo se leerían para un shell de inicio de sesión.

  • La --norcopción deja bashde leer los scripts de inicialización de shell personal que de otro modo se leerían para un shell interactivo.

Kusalananda
fuente
Mi env no reconoce esas opciones.
Paulo Carvalho el
@PauloCarvalho ¿Su sistema no es compatible env -i? ¿En qué sistema estás?
Kusalananda
Lo siento, funciona en el shell. Traté de ponerlo en un script y de alguna manera arrojó un error.
Paulo Carvalho
@PauloCarvalho Lo siento, no puedo ver qué comando ingresó o cuál fue el error que recibió.
Kusalananda
Genial, justo lo que estaba buscando. envpara limpiar mi entorno, y --noprofileevitar el abastecimiento / etc / profile and friends, y --norcevitar el abastecimiento ~ / .bashrc y amigos.
Felipe Alvarez
28

env -i somecommandejecuta un comando en un entorno vacío, como ya ha mencionado ams .

Muchos programas dependen de algunas variables de entorno importantes, por lo que es posible que desee conservarlas:

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

Alternativamente, puede iniciar sesión en un pequeño entorno de tiempo de inicio de sesión.

ssh localhost somecommand
Gilles
fuente
1
Funciona cuando se ejecuta el comando en cmdline. ¿Cómo pongo esto en shebang ?, ¡no parece funcionar !
balki el
Extraño, mi envno admite la --delimitación y hace env -i FOO=bar -- envintentos de ejecutar un comando llamado --.
antak
@antak Eso debería ser env -i -- FOO=bar env, en realidad. Culpa mía. No es que --sea ​​útil ya que lo que sigue no comienza con -.
Gilles
No me di cuenta de que siempre podías meterte en localhost, eso es un poco extraño. ¿Cuál es el caso de uso allí?
Edgar Aroutiounian
@EdgarAroutiounian Puede SSH a localhost si está ejecutando un servidor SSH. ¿Por qué los programadores se esforzarían por prohibirlo?
Gilles
4

Si bien la respuesta aceptada es correcta, lo que generalmente desea hacer es:

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

Esto le proporciona un bash básico pero funcional (igual que obtendría al iniciar sesión en modo no interactivo). Esto, por ejemplo, establece el idioma, la zona horaria, el INICIO, etc.

Marcin Raczkowski
fuente
Eso no funciona porque se env -iborra HOME, lo que significa bash -lque no puede encontrar su .bash_profileetc. Si desea un shell que es como lo que obtendría con un inicio de sesión nuevo, necesita una indirección adicional para configurar HOMEprimero.
Elliott Slaughter
Vea esta respuesta: unix.stackexchange.com/a/451389/157340
Elliott Slaughter el
1

El problema con la mayoría de las respuestas aquí es que env -idesaparece HOME, por lo que incluso si se ejecuta bash -len el interior, no leerá su .bash_profileetc. Si lo que está buscando es un shell que actúa como si acabara de hacer un nuevo inicio de sesión, usted Quisiera esto en su lugar:

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

Ejemplo:

$ 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
fuente
1
Tenga en cuenta que bashse ejecutará un shell de inicio de sesión .bash_logino .bash_profile. Para obtener un entorno limpio, use --noprofileo establezca HOMEun directorio que no tenga esos archivos. Supongo que depende de lo que quieras decir con "limpio".
Kusalananda
1
Sí, si quieres un shell con literalmente nada, solo sigue la respuesta original y hazlo env -i bash -c .... Esta respuesta es específicamente cuando desea un shell que parece que acaba de hacer un nuevo inicio de sesión en la máquina.
Elliott Slaughter
0

Para responder el comentario de balki (y responder mi propia pregunta en el proceso :-):

% 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
fuente
Cuando intento esto en mi línea shebang en CentOS 7.6, recibo este error de env:/usr/bin/env: invalid option -- ' ' Try '/usr/bin/env --help' for more information.
ScottJ
Si cambio el script para usar el argumento largo --ignore-environment, obtengo esto:/usr/bin/env: unrecognized option '--ignore-environment SOMETHING_TO_KEEP="$USER" PATH="$PATH" /bin/sh' Try '/usr/bin/env --help' for more information.
ScottJ