¿Bash y Zsh tienen un modo para hacer eco de lo que se expande el alias al presionar Enter?

¿Bash y Zsh tienen un modo para hacer eco de lo que se expande el alias al presionar Enter?

Por ejemplo, si tengo un

alias dbmigrate='rails db:migrate'

¿Existe algún modo o forma sencilla de configurar en Bash y Zsh para que cuando escribo en el shell:

$ dbmigrate  # press Enter

¿Hará eco de a qué se expande el alias antes de ejecutarlo?

Respuesta1

Enintento, existen las funciones alias-expand-liney history-and-alias-expand-linereadline, pero no están vinculadas a ninguna clave de forma predeterminada. Puede vincularlos usted mismo, por ejemplo con Control-T:

bind '"\C-T": history-and-alias-expand-line'

Intentar vincularse Entera sí mismo sería complicado, porque no cada vez que presiona Enterse ejecuta el comando (por ejemplo, no cuando es una canalización incompleta, etc.).

También existe la DEBUGtrampa, pero determinar si el usuario realmente ingresó el comando (por ejemplo, no lo inició desde PROMPT_COMMANDo desde una sustitución de comando en PS1) y si fue expandido con un alias será complicado; pero si estás de acuerdo con que se imprimacualquiercomando antes de ser ejecutado:

trap 'echo "> $BASH_COMMAND"' DEBUG

bash$ pwd
> pwd

Enzsh, simplemente puede definir una preexecfunción que imprima el comando expandido si es diferente del ingresado por el usuario:

preexec(){ [ $1 != $2 ] && print -r "> $2" }

zsh$ j
> jobs

Sin embargo, tenga en cuenta que algunos trucos de alias + historial no funcionarán correctamente si fuerza la expansión del alias. Por ejemplo, tengo un calias en bash para hacer cálculos como c 3.17 * 4.2, sin tener que escapar de *, (etc.:

alias c='_c=$(fc -nl -0); bc -l <<<${_c#*c} #'

Una vez que readline lo haya expandido, la línea actual del historial (la devuelta por fc -nl -0) será laexpandido, no el comando original, y todo se desmoronará.

Respuesta2

Los alias son simplemente sustituciones simples. Si desea hacer algo más sofisticado, como imprimir un mensaje antes de ejecutar el comando, necesita algo más poderoso: una función. Si desea que la definición parezca una definición de alias, puede definir una función que defina una función.

function verbose_alias {
  local name=${1%%=*} expansion=${1#*=}
  eval "function $name {
    printf >&2 '%s is an alias for %s\\n' \"$name\" \"$expansion\";
    $expansion \"\$@\";
  }"
}
verbose_alias dbmigrate='rails db:migrate'

Respuesta3

POSIX requiere lasetdominiotener esta opción

-x

   El shell escribirá en el error estándar un seguimiento para cada comando después de expandir el comando y antes de ejecutarlo. No se especifica si se rastrea el comando que desactiva el rastreo.

https://pubs.opengroup.org/onlinepubs/009604499/utilities/set.html

Así que puedes usar set -xo set -o xtraceen cualquier shell compatible. En bash puedes ver esto en la página de manual:

-x

   Después de expandir cada comando simple, para comando, comando de mayúsculas y minúsculas, comando de selección o aritmética para comando, muestre el valor expandido de PS4, seguido del comando y sus argumentos expandidos o la lista de palabras asociadas.

xtrace

   Igual que -x.

https://linux.die.net/man/1/bash

zsh también tiene una opción similar parasetincorporado

XTRACE( -x, ksh: -x)

   Imprime comandos y sus argumentos a medida que se ejecutan.

https://linux.die.net/man/1/zshoptions

También puede especificar la -xopción mientras ejecuta scripts o comandos.

bash -x -c "echo This will be printed before running; ll"
bash -x script-to-be-debugged.sh
zsh -x -c "...; 3; md did-you-see-the-aliases"
zsh -x buggy-script.sh

Tenga en cuenta que también expande los comandos que se ejecutan antes y después de cada mensaje, por lo que puede no ser deseable en muchas situaciones, por ejemplo, cuando usa gitvariables en su PS1. En mi máquina virtual Ubuntu limpia solo se imprime el comando en ejecución

Ver también¿Que es lo que set -xhace?

Otra opción es set -vo set -o verboseque no expande las variables antes de imprimir.

Respuesta4

Ese tipo de ayuda no está disponible de forma predeterminada en bash.

Las dos funciones relacionadas que están disponibles de forma predeterminada son:

  • shopt -s histverify

Si está configurado y se utiliza readline, los resultados de la sustitución del historial no se pasan inmediatamente al analizador de shell. En cambio, la línea resultante se carga en el búfer de edición de línea de lectura, lo que permite modificaciones adicionales.

Lo cual aborda la parte de una acción cuando Enterse presiona, pero solo con una expansión del historial en la línea de comando. Por ejemplo:

$ shopt -s histverify
$ echo "this is a test"
This is a test
$ echo !!
$ echo echo "this is a test"  <---- expanded by the simple use of enter!! 
  • Línea de lecturashell-expand-line

línea de expansión de shell (MCe)

Expande la línea como lo hace el caparazón. Esto realiza la expansión de alias e historial, así como todas las expansiones de palabras del shell. Consulte EXPANSIÓN DE LA HISTORIA a continuación para obtener una descripción de la expansión de la historia.

Esto es exactamente lo que estás pidiendo que se haga, pero la clave para que funcione es Ctrl...Alte

No conozco una solución que funcione con enter y se ejecute shell-expand-line, lo siento.

información relacionada