¿Cómo puedo obtener comandos de sudo para usar la configuración en /root/.bashrc

9

Me he personalizado .bashrccon varios alias, específicamente llyexport LS_OPTIONS='--color=auto'

Desafortunadamente, esto no funciona cuando se usa con sudo, por lo que también modifiqué /root/.bashrc, pero parece que esto no ha hecho ninguna diferencia.

sudo envespectáculos HOME=/rootySHELL=/bin/bash

¿Cómo puedo obtener sudocomandos para usar la configuración /root/.bashrc?

Entiendo que esto sucede solo cuando bashse ejecuta de forma interactiva, por lo que estoy abierto a cualquier otra sugerencia sobre cómo personalizar.

Milliways
fuente
@ daniel-gelling: siempre he sentido que este Q es un problema XY: meta.stackexchange.com/questions/66377/what-is-the-xy-problem . El título implica que quieren algo, /root/.bashrcpero en realidad lo que busca la Q son los alias de este archivo, esto no es posible por esto, unix.stackexchange.com/questions/1496/… .
slm
@slm Lo que estoy después es la adición de un método para bashrc - como lo he hecho en mi archivo .bashrc personal, así como el archivo .bashrc de raíz a "desactivar" la -ropción para crontab: crontab () { [[ $@ =~ -[iel]*r ]] && echo '"r" not allowed' || command crontab "$@" ;}. Esto funciona cuando inicias sesión como cualquier usuario, sin embargo, cuando lo ejecuto sudo crontab -rtodavía se ejecuta.
Daniel Gelling
@DanielGelling: mira si mi respuesta funciona para ti.
slm

Respuestas:

6

sudoejecuta un ejecutable, no un comando de shell. Entonces no sabe sobre alias. Si ejecuta sudo ls, es como sudo /bin/ls, no utiliza ningún lsalias que pueda tener.

Puede hacer sudo lsque se expanda el alias al poner lo siguiente en su .bashrc:

alias sudo='sudo '

Tenga en cuenta el espacio final, que le dice al shell que continúe la expansión de alias con la palabra que viene después sudo. Tenga en cuenta que expandir los alias después de sudo puede no ser siempre una buena idea, depende de qué tipo de alias tenga.

Además, sudo elimina la mayoría de las variables del entorno. Esto no afectará a un alias como alias ls='ls $LS_OPTIONS', porque esa es una variable de shell utilizada por el shell mientras expande el comando (y exportarlo no .bashrcsirve para nada). Pero afectaría a las variables que utiliza el comando, como LS_COLORS. Puede configurar sudo para mantener ciertas variables de entorno editando su configuración: ejecute visudoy agregue la línea

Defaults env_keep += "LS_COLORS"

Con esta configuración, sudo llle dará los colores a los que está acostumbrado.

Alternativamente, puede ejecutar un shell raíz con sudo -s. Este shell cargará su archivo de configuración ( ~/.bashrcpara bash). Dependiendo de cómo esté configurado sudo, esto puede mantenerse HOMEconfigurado en su directorio de inicio, o cambiarlo a /root. Puede forzar que el directorio de inicio se configure en raíz con sudo -Hs; por el contrario, para mantener el directorio de inicio original, ejecute sudo env HOME="$HOME" bash.

Gilles 'SO- deja de ser malvado'
fuente
3

Gracias a los que respondieron, que me impulsaron a leer man sudomás detenidamente.

sudo -s Si no se especifica ningún comando, se ejecuta un shell interactivo.

Este shell interactivo utiliza /root/.bashrcy, por lo tanto, incluye mis personalizaciones.

Requiere que el comando se ingrese por separado, pero esto está bien.

Milliways
fuente
2

Antecedentes

Siempre he sentido que esta pregunta es un problema XY . El título implica que quieren algo, /root/.bashrcpero en realidad lo que busca son los alias de este archivo (se cree que esto no es posible por esto). ¿Por qué mi script Bash no reconoce los alias? .

Básicamente, es por diseño que sus alias no se detectarán en sudoy en otros lugares porque no son portátiles, y esta es mi opinión sobre ellos también.

Cualquier cosa que esté en el entorno del usuario no debe ser asumida por los scripts y cualquier software que pueda ejecutarse en un cuadro determinado. Pero me doy cuenta de que hay escenarios en los que puede haber algunos alias en una cuenta de usuario determinada $HOME/.bashrcque otros quieran aprovechar en escenarios interactivos.

Con ese fin, simplemente puede decirle al intérprete de Bash que expanda los alias que encuentre durante el proceso de inicio de sesión fuera de los comportamientos normales de shell que se encuentran al usar sudo.

Ejemplo

Preparar

Para configurar las cosas, he agregado los siguientes alias, variables de entorno y funciones a mis usuarios /root/.bashrcy /root/.bash_profilearchivos raíz .

$ grep smurf ~/.bashrc
alias brc_smurf='echo "ran alias from /root/.bashrc"'
export brc_smurf_env='var from /root/.bashrc'
bpf_smurf_func() { echo 'ran func from /root/.bash_profile'; }

$ grep smurf ~/.bash_profile
alias bpf_smurf='echo "ran alias from /root/.bash_profile"'
export bpf_smurf_env='var from /root/.bash_profile'
brc_smurf_func() { echo 'ran func from /root/.bashrc'; }

Sin hacer nada de ninguno de estos trabajos (sin sorpresas):

$ sudo brc_smurf
sudo: brc_smurf: command not found

$ sudo bpf_smurf
sudo: bpf_smurf: command not found

Vemos que el aliascomando no muestra alias cuando se ejecuta en sudo:

$ sudo alias
$

Este comportamiento es su sugerencia de que no debe esperar que los alias sean accesibles. Pero seguimos ...

Paso # 1 - alias visibles

Si corremos bash -ci, podemos inducir a Bash a leer al menos nuestro $HOME/.bashrc:

$ sudo bash -ci 'alias' | grep smurf
alias brc_smurf='echo "ran alias from /root/.bashrc"'

Genial, ¿entonces tal vez podamos ejecutarlo?

$ sudo bash -ci 'alias; brc_smurf'
bash: alias; brc_smurf: No such file or directory

Paso 2 - shopt -s expand_aliases

No Una vez más, esto es por diseño, estamos haciendo algo que no se supone que debemos hacer, por lo que hay una serie de "seguridad" que tenemos que desactivar. la otra "seguridad" es Bash.

$ sudo bash -ci 'shopt -s expand_aliases; alias; brc_smurf'
alias brc_smurf='echo "ran alias from /root/.bashrc"'
alias cp='cp -i'
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
ran alias from /root/.bashrc

Aquí podemos ver nuestro mensaje /root/.bashrc, hemos ejecutado con éxito el alias del usuario raíz brc_smurf.

Paso # 3: ¿qué pasa con las env env?

Si está utilizando el método que se muestra arriba, estos también deberían funcionar.

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env'
ran alias from /root/.bashrc
var from /root/.bashrc

Paso 4: ¿qué pasa con las funciones?

Estos también funcionan como se esperaba:

$ sudo bash -ci 'shopt -s expand_aliases; brc_smurf; echo $brc_smurf_env;brc_smurf_func'
ran alias from /root/.bashrc
var from /root/.bashrc
ran func from /root/.bashrc

TLDR;

Puede hacer esto para obtener acceso a variables de entorno + alias de /root/.bashrc:

$ sudo bash -ci 'shopt -s expand_aliases; <cmds>'

Llevar lejos

Este método habilita el contenido de /root/.bashrc, no recoge el contenido de /root/.bash_profile.

Referencias

slm
fuente
Sí, aunque hay algunas diferencias menores entre ellos, no entremos en detalles aquí ;-). De todos modos, ¿podrían ayudarme con la situación que dije en los comentarios de la pregunta: usar funciones .bashrccon sudo; específicamente eliminar la -ropción de crontab?
Daniel Gelling
Está bien, pero esto significaría que tendría que correr: ¿en sudo bash -ci 'alias; shopt -s expand_aliases; echo $brc_smurf_env'lugar de un simple sudo echo $brc_smurf_env?
Daniel Gelling
Se puede quitar el alias, que era simplemente para mostrarles, que había necesidad de hacerlosudo bash -ci 'shopt -s expand_aliases; <cmds>'
SLM
Sería mucho escribir solo para editar mi crontab para root. Permítanme crear un alias para ello :-P
Daniel Gelling
@DanielGelling: sí, bienvenido a toda la diversión en las entrañas.
slm
0

Hay un montón de configuraciones en el archivo / etc / sudoers específicamente o configurar un entorno para cuando se ejecutan los comandos sudo (por ejemplo, asegurarse de que la RUTA solo tenga ubicaciones de confianza), pero dependiendo de lo que espera obtener de esto es posible que no pueda hacer lo que busca si se trata de ejecutar comandos reales en un shell para configurar el entorno. Sudoing específicamente no le da un shell de inicio de sesión raíz, por lo que no configurará un perfil regular para usted.

hvindin
fuente
0

Digamos que editamos /root/.bashrc para que sea:

$ sudo su -
Password: ******
# cat ~/.bashrc

echo "root bashrc file was read"
PATH=~/bin:$PATH
echo "$PATH"
export USERVAR=set
echo "$USERVAR"

umask 022
alias ll='ls $LS_OPTIONS -l'
alias l='ls $LS_OPTIONS -lA'

Permite cerrar sesión y volver a iniciar sesión para que bash lea el archivo:

# exit
$ sudo su -
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@here:~# alias l
alias l='ls $LS_OPTIONS -lA'
root@here:~# 

Como puede ver, se leyó el archivo, se cambió la RUTA y se establecieron los alias. Todo es funcional como lo solicite.

Sin embargo, sudo todavía no funcionará como esperabas.

root@here:~# exit
$ sudo env | grep USERVAR              # no output 
$ sudo env | grep PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

RUTA no ha cambiado. Puede haber formas de cambiar el camino en sudoers, pero le recomiendo encarecidamente que evite hacerlo. Y, de todos modos, los alias, las funciones y algunos otros cambios aún no se aplicarán cambiando solo la RUTA. Un archivo debe ser de origen. Hacer eso para cada script o comando le pedirá a la computadora que realice más trabajo sin ningún beneficio real. Los guiones no usan alias (no hay un uso práctico para ellos dentro de los guiones).

Entonces, solo inicie sesión, el .bashrcarchivo se cargará automáticamente y comenzará a funcionar.

Puedes comenzar bash así:

$ sudo bash
root bashrc file was read
/root/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
set
root@mail:/home/isaac/me/temp/clocks-master#

Pero como puede ver arriba, el pwd (el directorio de trabajo) no ha cambiado y, si inspecciona un poco más, algunas otras configuraciones tampoco han cambiado. Es por eso que el comando correcto es usar:

$ sudo su -

Si ese comando es demasiado largo para escribir, cree un alias o una función en el usuario (no root) donde se usará ese comando, algo como:

$ alias mysu='sudo su -'
$ mysu
# 
Isaac
fuente
0

TL; DR: puede usar sudo -ipara ejecutar una función definida /root/.bashrc(pero no un alias) y también tener acceso a las variables exportadas desde ese archivo:

argumentos del comando sudo -i 

Sin embargo, los alias no funcionan allí, pero puede convertirlos fácilmente en funciones si desea que estén disponibles sudo -i.

Siga leyendo para un análisis completo y más detalles.


Aquí hay algunos problemas, algunos sobre cómo funciona sudo y otros sobre cómo funciona bash en sí ...

De forma predeterminada, sudosolo buscará comandos y omitirá el shell, por lo que la ejecución sudo llsolo funcionará si hay un llejecutable en uno de los directorios $PATH. Entonces, para usar alias (o funciones) debe asegurarse de que se invoque un shell como parte del proceso.

Una forma sería ejecutar algo como sudo sho sudo bash, aunque moderno sudo(estoy probando esto en sudo 1.8.19p1) tiene opciones -sy -ipara ese propósito.

Entonces, un intento sería algo así sudo -s ll(lo que es equivalente a sudo bash -c 'll', suponiendo que su $SHELLes Bash, que parece ser el caso basado en lo rcfileque mencionó). Pero eso tampoco funciona, ya que inicia el shell en un modo no interactivo, modo sin inicio de sesión, que no lee ninguno de sus archivos de inicio. Es esencialmente lo mismo que si escribes un script de shell y lo usas #!/bin/bashpara ejecutarlo. Los alias (y funciones) que tienes en tu ~/.bashrcno serán accesibles desde ese script ...

Entonces la siguiente es la -iopción, que crea un shell de inicio de sesión. Eso es más prometedor, ya que va a leer sus archivos de inicio! Y sin embargo, sudo -i ll(equivalente a sudo bash -l -c 'll') todavía no funcionará. Entonces, ¿cómo es esto posible, dado que se lee la definición del llalias?

Bueno, la siguiente explicación aquí es que, por defecto, bash no expandirá los alias, excepto cuando el shell es interactivo ... Este shell iniciado por sudo -i(o bash -l) es un shell de inicio de sesión , pero aún no es interactivo.

Entonces, el siguiente paso es obtener un shell interactivo , que luego funciona :

sudo bash -i -c 'll'

(Tener inicio de sesión e interactivo también está bien, por supuesto, bash -l -i -c ...funcionará).

Otra alternativa es seguir usando un shell de inicio de sesión (no interactivo) pero pedirle explícitamente que expanda los alias, para que esto también funcione:

sudo bash -l -O expand_aliases -c 'll'

(El caso en el que bash era interactivo no necesitaba un shell de inicio de sesión , ya que es suficiente para leer los archivos de inicialización, pero este debe -lleerlos).

Estas son líneas de comando bastante largas ... Y también requieren que cite todo el comando de shell, por lo que si está llamando a un alias con argumentos, tendrá que convertir todo eso en una cadena ... Entonces es una especie de torpe de usar ...

Tenga en cuenta que antes estaba hablando de alias y funciones ... Eso fue a propósito, ya que las funciones en realidad son mucho más convenientes aquí. No necesita nada especial (como tener un shell interactivo o configurar una opción específica) para ejecutar funciones en un shell, siempre que obtenga su definición.

Entonces, si definió llcomo una función en lugar de un alias, podría usarla directamente con el -iatajo de sudo :

sudo -i ll

Y si tiene una línea de comando más larga, con argumentos, podría pasarlos directamente aquí también:

sudo -i ll -C -R /etc

(Comparar con sudo bash -i -c 'll -C -R /etc')

Las funciones también son mucho más flexibles y, por lo general, más fáciles de mantener ... Por lo general, es fácil convertir un alias en una función, la única advertencia es usar siempre "$@"donde se espera que se tomen argumentos adicionales (generalmente al final del alias.)

Por ejemplo, este alias:

alias ll='ls $LS_OPTIONS -l'

Podría convertirse en esta función:

ll () {
    ls $LS_OPTIONS -l "$@"
}

Son, para la mayoría de los propósitos, equivalentes. Y, como se mencionó anteriormente, la función debe ser accesible directamente desde sudo -i, por lo que es una ventaja adicional.

¡Espero que encuentre útil esta respuesta y explicación!

filbranden
fuente
DV - No creo que esto mejore la situación más de lo que ya está aquí tampoco.
slm
1
@slm yo creo que mi respuesta es la adición de algo, ya que no hay respuesta anterior se menciona la forma sudo -i command argumentsde ser capaz de ejecutar funciones de /root/.bashrcy tienen variables exportadas disponible. Pero veo cómo mi respuesta fue quizás demasiado larga y esa información estaba algo oculta allí ... Así que agregué un TL; DR para resumirlo (sin dejar de mantener los detalles técnicos de la investigación). Por favor, eche otro vistazo.
filbranden