¿Por qué sudo ignora los alias?

22

Estoy ejecutando Ubuntu 10.04 y lo uso upstartpara la gestión de demonios. Mi aplicación empresarial se ejecuta como daemon y debe ejecutarse como root debido a varios privilegios. P.ej:

sudo start my-application-long-ID
sudo stop my-application-long-ID
etc

Me gustaría presentar un aliaspara abreviar estos comandos como algo así como:

alias startapp='sudo start my-application-long-ID'

y ejecutarlo como startappy eso funciona, pero preferiría no tener sudo en el alias.

alias startapp='start my-application-long-ID'

no cuando se ejecuta usando sudo startapp, volviendo sudo: startapp: command not found.

Sin embargo, cuando agregué el alias:

alias sudo='sudo '

sudo startapp ahora funciona pero todavía tengo curiosidad por qué sudo ignora los alias.

anfibio
fuente
¿Corriste source ~/.bashrc? ¿Esto actualiza el archivo .bashrc y hace que los nuevos alias estén disponibles?
manu
@manu Sí, lo hice
anfibio
1
serverfault.com/questions/61321/how-to-pass-alias-through-sudo
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

Respuestas:

35

Veo la siguiente información desde aquí .

Cuando use sudo, use la expansión de alias (de lo contrario, sudo ignora sus alias)

alias sudo='sudo '

La razón por la que no funciona se explica aquí .

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, bash solo comprueba la primera palabra (sudo) en busca de un alias, ll se 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.

Ramesh
fuente
6

Los alias y las funciones se definen en un shell. Sudo es un programa externo. Por lo tanto, sudo no ve alias, funciones o componentes integrados de shell, solo comandos externos.

Los alias están destinados a ser nombres de comando alternativos, por lo que los shells solo los expanden en la posición del comando, no cuando son argumentos de los comandos. Zsh admite alias globales, que se expanden en cualquier lugar de la línea de comando, y se utilizan con moderación, ya que existe el riesgo de expandirlos accidentalmente, incluso en contextos donde el alias no tiene sentido.

Se puede decir sudo para invocar un shell: sudo sh -c '…shell command here…'. Sin embargo, sus alias habituales no estarán disponibles dentro de ese comando de shell, ya que normalmente se almacenan en un archivo como ~/.bashrco ~/.zshrcque solo se lee mediante shells interactivos.

alias sudo='sudo ', según lo propuesto por Ramesh , hace que el shell expanda los alias después sudo.

Gilles 'SO- deja de ser malvado'
fuente
1
¿ alias sudo='sudo 'Funciona también para ZSH?
CMCDragonkai
2
@CMCDragonkai Sí
Gilles 'SO- deja de ser malvado' el
1

Una solución para usuarios de zsh

Tanto en bash como en zsh, terminar un alias con un espacio hará que el shell expanda alias la siguiente palabra. Esto permite que algo como lo siguiente se expanda aliasmyalias

alias 'sudo=sudo '
sudo myalias

Desafortunadamente, esto se desmorona cuando tiene más de una palabra en su alias (como sudo -u someone. Sin embargo, puede abusar de la función zsh "alias globales" para expandir manualmente los alias en cualquier parte del comando.

alias -g '$= '

Esto crea un alias global llamado $(puede usar cualquier palabra que desee) que termina en un espacio. Esto hace que zsh expanda la siguiente palabra como un alias de comando regular. Dado que el alias se expande al espacio en blanco, no se tratará como un argumento. Esto permite que lo siguiente funcione.

% alias myalias=echo
% sudo -u someone myalias foo
sudo: myalias: command not found
% sudo -u someone $ myalias foo
foo

Incluso puede usar $varias veces en una línea de comando si tiene una anidación de comandos complicada. He encontrado esto lo suficientemente útil como para que tenga un lugar permanente en mi zshrc, sin embargo, el alias es lo suficientemente simple como para definir cuándo necesita usarlo.

Kevin Cox
fuente
0

Acabo de dar una respuesta alternativa aquí sin redefinirsudo con un alias.

En tu caso sería:

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

Todo en una línea, sin shells adicionales, sin redefiniciones de alias. ;-)

amado por Jesús
fuente
Oh, espera un minuto, lo entiendo, lo estás usando xargspara quitar las comillas, y grep para quitar las primeras =. Un poco inteligente, pero probablemente innecesario. eval "sudo $(alias aliasname | cut -d= -f2-)"es probable que sea mejor: xargsno siempre manejará las comillas correctamente, y podría haber más de una =.
mikeserv
@mikeserv Lamento que no lo hayas entendido ;-) xargsno quites las comillas. Es grep quien toma el comando resuelto entre comillas. Ya sabes type -a alias_namedevuelve algo como alias_name is aliased to command_within_quotes. Por cierto, he probado su comando y no funcionó en mi ubuntu :-(. ¿Es el regreso detype -a Diferente entre las versiones de Linux (lo dudo)?.
loved.by.Jesus
Sé lo que typehace - en bash. Sin embargo, entiendes que las citas se duplican, ¿verdad? ¿Lo has probado con un alias que contiene comillas simples? De todos modos, tienes razón acerca de que mi cosa no funciona: necesitas uno eval "sudo sh -c "$(...o eval "'sudo $(alias alias_name| cut -d\' -f2-)". La cuestión aliases que, básicamente eval, los aliasvalores predeterminados son s: la utilidad está especificada para generar su contenido y poder reintroducirlo de forma segura en el shell. Supongo que su xargsse implementa entonces para aplanar el espacio en blanco? Solo ten cuidado con eso, ¿de acuerdo?
mikeserv