sudo como otro usuario con su entorno

56

$ whoami
admin
$ sudo -S -u otheruser whoami
otheruser
$ sudo -S -u otheruser /bin/bash -l -c 'echo $HOME'
/home/admin

¿Por qué no $HOMEse configura como /home/otheruseraunque se invoque bash como un shell de inicio de sesión?

Específicamente, /home/otheruser/.bashrcno se obtiene. Además, /home/otheruser/.profileno se obtiene. - ( /home/otheruser/.bash_profileno existe)

usuario80551
fuente
Una solución a esta pregunta también resolverá la otra pregunta, es posible que desee eliminar la otra pregunta en esta situación.
Pavel Šimerda

Respuestas:

83

Para invocar un shell de inicio de sesión sudosimplemente use -i. Cuando no se especifica el comando, recibirá un indicador de shell de inicio de sesión; de lo contrario, obtendrá el resultado de su comando.

Ejemplo (shell de inicio de sesión):

sudo -i

Ejemplo (con un usuario especificado):

sudo -i -u user

Ejemplo (con un comando):

sudo -i -u user whoami

Ejemplo (usuario de impresión $HOME):

sudo -i -u user echo \$HOME

Nota: El carácter de barra diagonal inversa asegura que el signo de dólar llegue al shell del usuario objetivo y no se interprete en el shell del usuario llamante.

Acabo de comprobar el último ejemplo con strace que te dice exactamente lo que está sucediendo. El siguiente resultado muestra que se llama al shell con --loginy con el comando especificado, al igual que en su llamada explícita a bash, pero además sudo puede hacer su propio trabajo como configurar el $HOME.

# strace -f -e process sudo -S -i -u user echo \$HOME
execve("/usr/bin/sudo", ["sudo", "-S", "-i", "-u", "user", "echo", "$HOME"], [/* 42 vars */]) = 0
...
[pid 12270] execve("/bin/bash", ["-bash", "--login", "-c", "echo \\$HOME"], [/* 16 vars */]) = 0
...

Noté que estás usando -Sy no creo que sea una buena técnica en general. Si desea ejecutar comandos como un usuario diferente sin realizar la autenticación desde el teclado, puede utilizar SSH en su lugar. Funciona localhosttanto como para otros hosts y proporciona autenticación de clave pública que funciona sin ninguna entrada interactiva.

ssh user@localhost echo \$HOME

Nota: No necesita ninguna opción especial con SSH ya que el servidor SSH siempre crea un shell de inicio de sesión para que el cliente SSH acceda a él.

Pavel Šimerda
fuente
2
sudo -i -u user echo \$HOMEno funciona para mi Salida: $HOME. strace da el mismo resultado que el tuyo. ¿Cual es el problema?
John_West
No tengo idea, todavía funciona para mí, tendría que verlo o incluso tocar el sistema.
Pavel Šimerda
10

Le estás dando demasiado crédito a Bash. Todo "shell de inicio de sesión" significa para Bash qué archivos se obtienen al inicio y apagado. La $HOMEvariable no figura en ella.

Los documentos de Bash explican un poco más qué significa el shell de inicio de sesión: https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html#Bash-Startup-Files

De hecho, Bash no hace nada para configurar $HOME. $HOMEse establece mediante lo que invoca el shell (inicio de sesión, ssh, etc.), y el shell lo hereda. Lo que inició su shell como administrador configurado $HOMEy luego ejecutado bash, sudopor diseño, no altera el entorno a menos que se lo pida o configure para hacerlo, de modo bashque otro usuario lo haya heredado de su shell.

Si desea sudomanejar más del entorno de la manera que espera, mire el -iinterruptor para sudo. Tratar:

sudo -S -u otheruser -i /bin/bash -l -c 'echo $HOME'

La página de manual de sudo lo describe con más detalle, aunque no muy bien, creo: http://linux.die.net/man/8/sudo

Jeff Snider
fuente
44
$ HOME no está establecido por bash - Gracias, no lo sabía.
user80551
Busque strace en mi respuesta. Muestra que no necesita construir la /bin/bash -l -c 'echo $HOME'línea de comando usted mismo cuando lo usa -i.
Pavel Šimerda
1
Esa sudosintaxis arrojó un error en mi máquina. ( suusa la -copción, pero no creo que lo sudohaga). Tuve mejor suerte con:HomeDir=$( sudo -u "$1" -H -s echo "\$HOME" )
palswim
Sí, @palswim tiene razón. No estoy seguro -S(no lo necesitaba, así que lo dejé fuera), pero -cno funciona aquí, en su -slugar lo necesitas .
polynomial_donut