¿Cómo probar posibles conflictos al usar alias en bashrc?

12

¿Hay una manera simple de enumerar todos los conflictos de comandos que se han producido en el sistema debido a la actualización de bashrc que involucra comandos de alias?

Por ejemplo, alguien escribe alias ls=/path/to/user-generated/executableen bashrc. ¿Cómo se descubre que esto está enmascarando un comando real ( ls)? Una forma parece ser ejecutar todos los alias antes y después de obtener bashrc y diferenciar la salida. ¿Hay alguna forma mejor?

Estoy ejecutando Ubuntu 12.04.

bash --version

GNU bash, versión 4.2.24 (1) -release (i686-pc-linux-gnu)

usuario13107
fuente
Como nota al margen, generalmente es más útil que las personas respondan si proporciona su versión de bash, en lugar de la versión del sistema operativo al hacer una pregunta específica para bash.
jordanm
@jordanm Actualizado.
usuario13107

Respuestas:

8

Para averiguar qué comandos están enmascarados por alias, haga algo como esto:

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'

Explicación

aliassolo enumera los alias definidos y sedextrae su nombre. El ciclo while se ejecuta type -taen cada uno de ellos e awkimprime las líneas que contienen alias y archivo.

Thor
fuente
15

Puede usar typepara averiguar cómo bash interpretaría un comando.

choroba
fuente
Por ejemplo, type lsimprime ls is aliased to `ls --color=auto'aquí.
l0b0
Funciona con lo mismo which, pero ahora no sé si ambos (tipo, qué) construcciones de shell son iguales.
matemáticas
@math: type whichte dice which is /usr/bin/which, por lo que no es un incorporado. Por lo tanto, no puede decirle si algo está incorporado o no (por ejemplo, which echoversus type echo).
choroba
Supongo que depende del shell que uses: type which which is a shell builtinestoy usando el zsh.
matemáticas
@math: la pregunta original está etiquetada / bash.
choroba
7

Como su primera pregunta, no hay forma de enumerar los conflictos, ya que bash usa una tabla hash internamente, solo registra la última anulación.

Para averiguar si un comando es un alias, use alias lsen su caso, si le dice algo como "no encontrado", entonces no es un alias, de lo contrario lo es.

Para iniciar la función original sin tener en cuenta el alias, prefija una barra diagonal, por ejemplo \ls, lanzará el hash real ls, ignore el alias.

EDITAR

Si desea saber rápidamente si un comando es un alias, puede habilitar el modo de depuración set -xahora, si ejecuta ls:

ingrese la descripción de la imagen aquí

Verá una salida de depuración del comando real que se está ejecutando

Para desactivar el modo de depuración, use set -

margarita
fuente
Gracias. Pero no entendí el aliaspapel. ¿Qué sucede si un usuario no sabe que existe un comando (por ejemplo ls)? Lo único que parece saber después de correr alias lses a qué se asigna y no a qué se asignó originalmente. Supongo que uno tendrá que ejecutar todos los comandos con y sin \ para encontrar conflictos.
user13107
@ user13107 actualizó la respuesta
daisy
Gracias. ¿Cómo desarmo el rastreo?
usuario13107
@ user13107 actualizado nuevamente ;-P
daisy
1
"no hay forma de enumerar los conflictos", simplemente no eres lo suficientemente imaginativo.
camh
6

Puede usar bash builtin compgenpara obtener una lista de todos los comandos y todos los alias que usa compgen -ac. Cualquier comando que también sea un alias se duplicará en esta lista, por lo que la solución simple e ingenua es buscar duplicados en la salida de compgen -ac.

Sin embargo, también pueden aparecer duplicados si un comando está en la ruta dos veces. Por ejemplo, tengo /bin/whichy /usr/bin/whichasí compgen -aclo enumeraré whichdos veces aunque no sea un alias.

Entonces, lo que se necesita es obtener todos los duplicados compgen -acy compararlos con una lista de alias. Solo los duplicados que también son alias son esos alias que ocultan comandos. Podemos hacer esto con el comm(1)comando y con la sustitución del proceso bash.

comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d) 

compgen -a | sortes la lista de todos los alias (ordenados por comm). compgen -ac | sort | uniq -des la lista de todos los duplicados de la lista de comandos y alias. comm -12genera solo aquellas líneas que son comunes a ambos.

camh
fuente
5

Puede usar la función de depuración de shell para ver exactamente lo que sucede cuando bash invoca un shell interactivo. Lo siguiente debería mostrarle todos los alias que se asignan cuando se genera un shell interactivo desde un shell de inicio de sesión:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> habilitar depuración
  • -l -> shell de inicio de sesión
  • -i -> shell interactivo
  • -c -> comando

Se requiere ejecutar el comando exit para que el shell regrese. En -ieste caso, se requiere porque bash no configuraría un entorno interactivo para ejecutar un comando de lo contrario.

Aquí hay un ejemplo de mi sistema:

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'

Para ver qué archivo se obtuvo por última vez cuando se asignó el alias para determinar el archivo en el que se produjo, puede extender el grep:

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '

Esto puede devolver falsos positivos, pero debería estar bien si está inspeccionando manualmente los datos devueltos. El número de símbolos '+' delante del comando ejecutado indica la profundidad.

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2

En esta salida de muestra, muestra que .bashrc establece un alias para ls, .foo alias t, y luego .bashrc anula el alias anterior de t.

jordanm
fuente
Gracias. Esto es ciertamente útil, pero no es capaz de ver cómo encuentra el conflicto creando alias.
usuario13107
@ user13107 Agregué algunos detalles más que deberían ser útiles. Establecer un alias en un nuevo valor no es un alias "conflictivo". Es un comportamiento normal documentado, por lo que se necesita una forma circular.
jordanm