Ejecutar un comando sin heredar el entorno de los padres

14

¿Hay alguna forma de ejecutar un comando "como si" estuviera en una nueva sesión de inicio de sesión?

Ya lo he intentado env -i. Sin embargo, no quiero tratar con varias variables ENV que tengo que configurar o desarmar.

También lo intenté bash -c "some command"y bash -l -c "some commmand", pero todos copian el entorno actual.

Lo más cerca que he llegado es una solución de ghetto: ssh me@localhost "some command"

dgo.a
fuente
Use /bin/bash --loginpara obtener ese comportamiento. Lo uso, por ejemplo, para obtener un adecuado $PATH.
Daniel Beck
Ese es el equivalente de /bin/bash --l, que ya probé. Copia el entorno original. Inténtelo: export SOME_VAL=something. Entonces /bin/bash --login. Entonces env | grep SOME_VAL. El valor estará ahí.
dgo.a

Respuestas:

12

Aquí hay una respuesta que no requiere privilegios de sudo o la contraseña del usuario, pero que proporciona un entorno como el que obtendría con un inicio de sesión nuevo.

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

Desglosando esto para una explicación:

  1. env -i HOME="$HOME": Limpia el medio ambiente. El -iestablece un entorno vacío sin variables de ningún tipo . Esto es problemático porque significa que si intentas ejecutarlo ingenuamente bash -l, no cargará tu .bash_profileetc. porque HOMEno está configurado. Para mitigar esto, pasamos explícitamente HOME="$HOME", creando un entorno donde HOME(y solo HOME) se establece.

  2. bash -l -c ...: Ejecuta el comando deseado en un shell de inicio de sesión. Querrá un shell de inicio de sesión para esto porque estamos comenzando desde un entorno limpio y necesitamos volver a cargar todo.

Notablemente:

  • Esto no requiere privilegios de sudo (la sudoversión sí).
  • Esto no requiere escribir la contraseña del usuario (la suversión sí).
  • Esto no requiere ejecutar un servidor SSH y tener una clave sin contraseña que pueda usarse para volver a iniciar sesión en la máquina (la sshversión sí).
Elliott Slaughter
fuente
Gracias Elliott. Parece tan simple y obvio ... ahora que me lo han señalado.
dgo.a
12
su -l $USER

sudo -u $USER -i

Para algo aún más agresivo env -i bash, pero eso desestabiliza todo, incluidos $ HOME y $ TERM.

usuario1686
fuente
2
¡Gracias! El segundo comando me da exactamente lo que quiero. Busqué más de 2 horas y no encontré nada parecido a tu respuesta. Según su respuesta, volví a man sudoencontrar: "si el usuario objetivo es el mismo que invoca, no se requiere contraseña". ( suParece que siempre pide una contraseña.) Soy tan tonto por haber pasado por alto algo tan simple en el primer párrafo de una manpágina :( En primer lugar, evité sudo porque supuse que siempre pedía una contraseña. Gracias de nuevo!
dgo.a
1
solo una pista para otros ... si ha iniciado sesión ya $USERque deberá iniciar sesión como root y luego sudo -u ...como su usuario. Si solo haces lo sudo -uque el usuario heredarás.
Adam Gent
esto no funciona, obviamente, si no tiene sudoacceso. ¿Hay algún método alternativo que no requiera sudo?
user5359531
@ user5359531: Sí - su -l $USER.
user1686
1
que pide una contraseña; He iniciado sesión a través de la autenticación de clave ssh, por lo que ni siquiera sé cuál es la contraseña. Y una solicitud de contraseña va a matar la capacidad de script. Hasta ahora parece que ssh $USER@localhost <command>funciona mejor
user5359531