Bash e Zsh têm um modo para ecoar o que o alias expande ao pressionar Enter?

Bash e Zsh têm um modo para ecoar o que o alias expande ao pressionar Enter?

Por exemplo, se eu tiver um

alias dbmigrate='rails db:migrate'

existe um modo ou maneira simples de configurar no Bash e Zsh para que quando eu digitar no shell:

$ dbmigrate  # press Enter

ele irá ecoar o que o alias expande antes de executá-lo?

Responder1

Emfesta, existem as funções alias-expand-linee history-and-alias-expand-linereadline, mas elas não estão vinculadas a nenhuma chave por padrão. Você mesmo pode vinculá-los - exemplo com Control-T:

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

Tentar vincular Enter-se seria confuso, porque nem sempre que você pressiona Entero comando é executado (por exemplo, não quando é um pipeline incompleto, etc.).

Há também a DEBUGarmadilha, mas determinar se o comando foi realmente inserido pelo usuário (por exemplo, não iniciado a partir de PROMPT_COMMANDou a partir de uma substituição de comando em PS1) e se foi expandido por alias será complicado; mas se você concordar com a impressãoqualquercomando antes de ser executado:

trap 'echo "> $BASH_COMMAND"' DEBUG

bash$ pwd
> pwd

Emzsh, você pode simplesmente definir uma preexecfunção que imprima o comando expandido se for diferente daquele digitado pelo usuário:

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

zsh$ j
> jobs

No entanto, tenha cuidado, pois alguns truques de alias + histórico não funcionarão corretamente se você forçar a expansão do alias. Por exemplo, eu tenho um calias no bash para fazer cálculos como c 3.17 * 4.2, sem precisar escapar de *,, (etc:

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

Depois que readline o expandiu, a linha atual do histórico (aquela retornada por fc -nl -0) será aexpandido, não o comando original, e tudo desmoronará.

Responder2

Aliases são apenas substituições simples. Se quiser fazer algo mais sofisticado, como imprimir uma mensagem antes de executar o comando, você precisa de algo mais poderoso: uma função. Se quiser que a definição se pareça com uma definição de alias, você pode definir uma função que defina uma função.

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'

Responder3

POSIX requer osetcomandoter essa opção

-x

   O shell deve gravar no erro padrão um rastreamento para cada comando após expandir o comando e antes de executá-lo. Não é especificado se o comando que desativa o rastreamento é rastreado.

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

Então você pode simplesmente usar set -xou set -o xtraceem qualquer shell compatível. No bash você pode ver isso na página de manual:

-x

   Depois de expandir cada comando simples, para comando, comando case, comando select ou aritmética para comando, exiba o valor expandido de PS4, seguido pelo comando e seus argumentos expandidos ou lista de palavras associadas.

xtrace

   Igual a -x.

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

zsh também tem uma opção semelhante para osetconstruídas em

XTRACE( -x, ksh: -x)

   Imprima comandos e seus argumentos à medida que são executados.

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

Você também pode especificar a -xopção ao executar scripts ou 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

Esteja ciente de que ele também expande os comandos executados antes e depois de cada prompt, portanto, pode não ser desejável em muitas situações, por exemplo, quando você usa gitvariáveis ​​em seu PS1. Na minha VM Ubuntu limpa, apenas o comando em execução é impresso

Veja tambémO que set -xfaz?

Outra opção é set -vou set -o verboseque não expande as variáveis ​​antes de imprimir

Responder4

Esse tipo de ajuda não está disponível por padrão no bash.

As duas funções relacionadas que estão disponíveis por padrão são:

  • shopt -s histverify

Se definido e readline estiver sendo usado, os resultados da substituição do histórico não serão passados ​​imediatamente para o analisador de shell. Em vez disso, a linha resultante é carregada no buffer de edição readline, permitindo modificações adicionais.

Que aborda a parte de uma ação quando Enteré pressionado, mas apenas com uma expansão do histórico na linha de comando. Por exemplo:

$ 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!! 
  • Leia a linhashell-expand-line

linha de expansão de shell (MCe)

Expanda a linha como o shell faz. Isso executa a expansão de alias e histórico, bem como todas as expansões de palavras do shell. Consulte EXPANSÃO DO HISTÓRICO abaixo para obter uma descrição da expansão do histórico.

Isso é exatamente o que você está pedindo que seja feito, mas a chave para fazer funcionar é Ctrl- Alt-e

Não conheço uma solução que funcione com enter e execute shell-expand-line, desculpe.

informação relacionada