¿Cómo puedo ver qué comando se ejecutó realmente en el shell, a través de un alias o función

20

Tengo una función bash (o alias), por ejemplo function install() {sudo apt-get install $@}. Al ejecutar el comando install dicelab, lo que espero que realmente se ejecute es sudo apt-get install dicelab. ¿Dónde puedo ver lo que realmente fue ejecutado por el shell? Me gustaría asegurarme de que mis alias más complicados funcionen como se esperaba.

Alon Aviv
fuente
¿Es eso $@parte de tu alias? Recuerde que los alias realmente no admiten argumentos, que se expandirán a los parámetros posicionales (si los hay) del contexto que llama al alias. La forma habitual de ejecución somealias some argsfunciona simplemente expandiendo el alias y dejando los argumentos para seguirlo. Si realmente desea poder acceder a los argumentos, utilice una función y cite el"$@"
ilkkachu
2
Posible duplicado de Resolver alias anidados a sus comandos de origen
DarkHeart
1
@AlonAviv, bien. :) Aún así, es mejor acostumbrarse a citar eso "$@", los argumentos con espacios en blanco o caracteres glob se quemarán de lo contrario.
ilkkachu
1
@DarkHeart Esto no es duplicado. La otra pregunta no se refiere a las funciones de shell.
Kusalananda
2
Tampoco fue este hasta que fue editado para cambiar completamente su tema (e invalidar una de las respuestas existentes).
Michael Homer

Respuestas:

29

Uso set -xen la cáscara.

$ alias hello='echo hello world!'
$ hello
hello world!

$ set -x
$ hello
+ echo hello world!
hello world!

El uso de set -xvueltas en la xtraceopción del shell ( set +xlo apaga) y debería funcionar en toda Bourne-como conchas, como bash, dash ksh93, pdkshy zsh. Esto hace que el shell muestre el comando que se ejecuta después de que se hayan realizado expansiones de alias y expansiones variables, etc.

El resultado estará en la secuencia de error estándar del shell (al igual que el indicador ordinario), por lo que no interferirá con las redirecciones del resultado estándar, y estará precedido por un indicador definido por la PS4variable del shell ( +␣por defecto).

Ejemplo con algunas funciones:

$ world () { echo "world"; }
$ hello () { echo "hello"; }
$ helloworld () { printf '%s %s!\n' "$(hello)" "$(world)"; }

$ helloworld
hello world!

$ set -x
$ helloworld
+ helloworld
++ hello
++ echo hello
++ world
++ echo world
+ printf '%s %s!\n' hello world
hello world!

Estoy corriendo con set -xtodos mis shells interactivos por defecto. Es agradable ver lo que realmente se ejecutó ... pero he notado que la finalización programable de pestañas, etc., puede causar resultados de rastreo no deseados en algunos shells.

Kusalananda
fuente
14

Podrías usar shell-expand-line, que está obligado a Control- Alt- epor defecto:

$ bind -p | grep shell-expand-line
"\e\C-e": shell-expand-line

Entre otras cosas, reemplazará los alias en la línea actual con su definición para que pueda ver un comando que todavía va a ejecutar. Ejemplo:

$ install dicelab # now press C-Alt-e
$ sudo apt-get install  dicelab # the above line will be replaced with this
Arkadiusz Drabczyk
fuente
Esta es una buena característica. ¿sabes si zsh tiene un comando equivalente a shell-expand-line?
the_velour_fog
Lo siento, no lo hago porque no lo uso zsh. Pero algunas personas han tenido sus propias ideas: wiki.math.cmu.edu/iki/wiki/tips/20140625-zsh-expand-alias.html
Arkadiusz Drabczyk
@the_velour_fog, vea Resolver todos los alias en una línea de comando zsh
Stéphane Chazelas
1

Puede usar bash builtin typepara ver un alias o una definición de función que va a ejecutar:

$ type ls
ls is aliased to `ls --color=auto -p'

$ type -a ls
ls is aliased to `ls --color=auto -p'
ls is /bin/ls

$ install() { sudo apt-get install "@"; }

$ type install
install is a function
install () 
{ 
    aptitude install "@"
}
belkka
fuente