Alias ​​no disponibles cuando se usa sudo

161

Estuve jugando con alias hoy y noté que los alias no parecen estar disponibles mientras uso sudo:

danny@kaon:~$ alias
alias egrep='egrep --color=auto'
alias fgrep='fgrep --color=auto'
alias grep='grep --color=auto'
alias l='ls -CF'
alias la='ls -A'
alias ll='ls -alF'
alias ls='ls --color=auto'

danny@kaon:~$ ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //

danny@kaon:~$ sudo -i
root@kaon:~# ll -d /
drwxr-xr-x 23 root root 4096 2011-01-06 20:29 //
root@kaon:~# exit
logout

danny@kaon:~$ sudo ll -d /
sudo: ll: command not found

¿Hay alguna razón por la que no puedas usar alias mientras lo usas sudo?

kemra102
fuente
¿Declaraste ese alias en .bashrc en / root /
Luciano Facchinelli
2
@LucianoFacchinelli: /root/.bashrcno se lee cuando se ejecuta un comando a través de sudo.
Flimm
serverfault.com/questions/61321/how-to-pass-alias-through-sudo
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
@Flimm: ¿Qué pasa sudo -i?
Evi1M4chine

Respuestas:

251

Agregue la siguiente línea a su ~/.bashrc:

alias sudo='sudo '

Del manual de bash :

Los alias permiten que una cadena se sustituya por una palabra cuando se usa como la primera palabra de un comando simple. El shell mantiene una lista de alias que pueden establecerse y no con los comandos incorporados alias y unalias.

La primera palabra de cada comando simple, si no se cita, se verifica para ver si tiene un alias . Si es así, esa palabra se reemplaza por el texto del alias. Los caracteres '/', '$', '' ',' = 'y cualquiera de los metacaracteres de shell o caracteres de comillas enumerados anteriormente pueden no aparecer en un nombre de alias. El texto de reemplazo puede contener cualquier entrada de shell válida, incluidos metacaracteres de shell. La primera palabra del texto de reemplazo se prueba en busca de alias, pero una palabra que es idéntica a un alias que se expande no se expande por segunda vez. Esto significa que uno puede alias ls a "ls -F", por ejemplo, y Bash no intenta expandir recursivamente el texto de reemplazo. Si el último carácter del valor de alias es un espacio o un carácter de tabulación, entonces la siguiente palabra de comando que sigue al alias también se verifica para la expansión de alias .

(El énfasis es mío).
Bash solo verifica la primera palabra de un comando para un alias, cualquier palabra después de eso no se verifica. Eso significa que en un comando como sudo ll, solo la primera palabra ( sudo) es verificada por bash para un alias, llse ignora. Podemos decirle a bash que verifique la siguiente palabra después del alias (es decir sudo) agregando un espacio al final del valor de alias.

Isaias
fuente
18
Muy buena solución.
ulidtko
Entonces, básicamente, el problema se reduce al hecho de que sudo simplemente está programado de tal manera que no verifica el alias, por lo tanto, no se encuentra ll.
kemra102
2
Leer la documentación obviamente beneficia mucho :-)
biocyberman
44
¿Se romperá esto si uso una bandera de sudo, por ejemplo sudo -H ll?
Mark E. Haase el
1
@mehaase Sí, lo intenté y se rompe.
user31389
5

Escribí una función Bash para que sombree sudo.

Comprueba si tengo un alias para el comando dado y ejecuta el comando con alias en lugar del literal con sudoen ese caso.

Aquí está mi función como one-liner:

sudo() { if alias "$1" &> /dev/null ; then $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}" ; else command sudo $@ ; fi }

O bien formateado:

sudo() { 
    if alias "$1" &> /dev/null ; then 
        $(type "$1" | sed -E 's/^.*`(.*).$/\1/') "${@:2}"
    else 
        command sudo "$@"
    fi 
}

Sin embargo, puede agregarlo a su .bashrcarchivo, no olvide obtenerlo o reiniciar su sesión de terminal para aplicar los cambios.

Byte Commander
fuente
Sería maravilloso si esto también funcionara para sudo -H ll.
uav
3

Los alias son específicos del usuario; debe definirlos en /root/.bashrc

Ragnar123
fuente
3
Ellos ya están bajo /root/.bashrc así que no es un problema
kemra102
1
Esta respuesta sólo sería correcto para la situación en la que está utilizando el shell como raíz, al igual que con sudo -so sudo -i(y solamente si se ejecuta por sí mismo para conseguir un intérprete de comandos, no con los sudo -s command...o sudo -i command...las formas) o sudo bash, o sudo su, o la situación en la que He habilitado los inicios de sesión raíz y tiene un shell raíz de esa manera. Cuando un usuario no root se ejecuta sudo command...desde su propio shell, la expansión de alias se realiza mediante su propio shell no root. sudono expande los alias, por lo que, aplicada a la situación descrita en la pregunta , esta respuesta es incorrecta.
Eliah Kagan
3

La respuesta de @Alvins es la más corta. ¡Sin duda! :-)

Sin embargo, pensé en una solución de línea de comando para ejecutar un comando con alias en sudo donde no hay necesidad de redefinir sudocon un aliascomando.

Aquí está mi propuesta para aquellos a quienes les puede interesar:

Solución

type -a <YOUR COMMAND HERE> | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Ejemplo

En el caso del llcomando

type -a ll | grep -o -P "(?<=\`).*(?=')" | xargs sudo

Explicación

cuando tiene un alias (como :) llel comando type -adevuelve la expresión con alias:

$type -a ll
ll is aliased to `ls -l'

con grepusted seleccione el texto entre el acento 'y el apóstrofe' en ese casols -l

Y xargsejecuta el texto seleccionado ls -lcomo parámetro de sudo.

Sí, un poco más pero completamente limpio ;-) No es necesario redefinir sudocomo alias.

amado por Jesús
fuente
3
Podría ser más simple si usó el aliasincorporado, ya que su salida es más limpia. alias llsalidas alias ll='ls -ahlF'.
muru
Aquí está la versión que incorpora la sugerencia de @ Muru: alias ll | sed "s/.*'\(.*\)'.*/\1/g" | xargs sudo.
ACK_stoverflow
Creo que el objetivo de la pregunta original era ahorrar trabajo al no tener que hacerlo sudo -iprimero, ejecutar el comando con alias, sino hacerlo de inmediato. Tener un comando tan complejo derrota eso. Podrías hacer lo primero y ser mucho más rápido.
Evi1M4chine
1

Tengo otra buena solución, que también agrega un poco de confianza:

Use bash complete para reemplazar automáticamente las palabras detrás sudocon sus alias al presionar tab.

Guarde esto como /etc/bash_completion.d/sudo-alias.bashcomp, y debería cargarse automáticamente al iniciar el shell interactivo:

_comp_sudo_alias() { from="$2"; COMPREPLY=()
  if [[ $COMP_CWORD == 1 ]]; then
    COMPREPLY=( "$( alias -p | grep "^ *alias $from=" | sed -r "s/^ *alias [^=]+='(.*)'$/\1/" )" )
    return 0
  fi
  return 1
}
complete -o bashdefault -o default -F _comp_sudo_alias sudo

Luego inicie sesión en una nueva terminal, y debería estar listo para comenzar.

Evi1M4chine
fuente
Hay una manera de obtener una lista de alias, especialmente para completar:compgen -a
muru
@muru: Gracias, pero en este caso necesito los valores, no las claves. Entonces, el alias que se ingresó será reemplazado por. Escribe el alias (como en sudo ll), presiona [TAB ↹], y el script encuentra llen la lista de asignaciones de alias, corta lo que se le asigna y lo inserta. (Entonces obtendrías, p sudo ls -lahvF --color=auto --time-style=long-iso. Ej .)
Evi1M4chine
0

Tengo una solución diferente por la cual no es necesario agregar sudocomo un alias. Ejecuto Linux Mint 17.3 pero debería ser bastante similar a Ubuntu.

Cuando eres root, entonces .profilese ejecuta desde su directorio de inicio. Si no sabe cuál es el directorio de inicio en la raíz, puede verificar con:

sudo su
echo $HOME

Como puede ver, el hogar de rootes /root/. Verifique su contenido:

cd $HOME
ls -al

Debería haber un .profilearchivo. Abra el archivo y agregue las siguientes líneas:

if [ "$BASH" ]; then
    if [ -f ~/.bash_aliases];then
        . ~/.bash_aliases 
    fi
fi

Básicamente, lo que hace este script bash es buscar un archivo llamado .bash_aliases. Si los archivos están presentes, ejecuta el archivo.

Guarde el .profilearchivo y cree sus alias .bash_aliases. Si ya tiene el archivo de alias listo, copie el archivo en esta ubicación

¡Vuelva a iniciar el terminal y listo!

Karthik Ramakrishnan
fuente
0

La respuesta más votada es excelente. Sin embargo, si escribe sudo -iy se eleva a un indicador de sudo ( #), no tendrá los alias que desea usar.

Para utilizar sus alias (y todo lo demás) en el #indicador, use:

sudo cp "$PWD"/.bashrc /root/.bashrc

Donde "$ PWD" se expande automáticamente en "/ home / YOUR_USER_NAME"

WinEunuuchs2Unix
fuente
0

@ WinEunuuchs2Unix: se $PWDexpande al "directorio de trabajo actual". Creo que quieres $HOME.

Además, para la mayoría de las situaciones, probablemente sea mejor tener un archivo .bashrc raíz separado. De hecho, lo convertiría en un archivo real /root, un enlace suave a él en el directorio de inicio del usuario (por ejemplo, .bashrc_root), y lo buscaría en el .bashrcarchivo del usuario . Si en algún momento posterior esta cuenta de usuario privilegiada ya no está presente, el .bashrcarchivo raíz todavía está disponible para otros usuarios.

Shaun Griffith
fuente