Verfügen Bash und Zsh über einen Modus, um beim Drücken der Eingabetaste die Erweiterung des Alias ​​wiederzugeben?

Verfügen Bash und Zsh über einen Modus, um beim Drücken der Eingabetaste die Erweiterung des Alias ​​wiederzugeben?

Wenn ich beispielsweise eine

alias dbmigrate='rails db:migrate'

Gibt es einen Modus oder eine einfache Möglichkeit, Bash und Zsh so zu konfigurieren, dass beim Eintippen in die Shell Folgendes angezeigt wird:

$ dbmigrate  # press Enter

Wird vor der Ausführung eine Echo-Ausgabe der Erweiterung des Alias ​​ausgegeben?

Antwort1

InSchlag, es gibt die Funktionen alias-expand-lineund history-and-alias-expand-linereadline, aber sie sind standardmäßig nicht an irgendwelche Tasten gebunden. Sie können sie selbst binden -- Beispiel mit Control-T:

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

Der Versuch, die Bindung Enterselbst durchzuführen, wäre chaotisch, da Enterder Befehl nicht bei jedem Drücken ausgeführt wird (z. B. nicht, wenn es sich um eine unvollständige Pipeline usw. handelt).

Es gibt auch die DEBUGFalle, aber festzustellen, ob der Befehl tatsächlich vom Benutzer eingegeben wurde (z. B. nicht von PROMPT_COMMANDoder von einer Befehlsersetzung in gestartet PS1wurde) und ob er durch einen Alias ​​erweitert wurde, wird schwierig sein; aber wenn Sie damit einverstanden sind, wird gedrucktbeliebigBefehl vor der Ausführung:

trap 'echo "> $BASH_COMMAND"' DEBUG

bash$ pwd
> pwd

Inzshkönnen Sie einfach eine preexecFunktion definieren, die den erweiterten Befehl druckt, wenn er von dem vom Benutzer eingegebenen abweicht:

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

zsh$ j
> jobs

Beachten Sie jedoch, dass einige Alias ​​+ Verlaufstricks nicht richtig funktionieren, wenn Sie den Alias ​​zwangsweise erweitern. Beispielsweise habe ich cin Bash einen Alias, um Berechnungen wie durchzuführen , ohne die , , usw. c 3.17 * 4.2maskieren zu müssen :*(

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

fc -nl -0Sobald readline es erweitert hat, ist die aktuelle Zeile aus dem Verlauf (die von zurückgegebene ) dieerweitert, nicht der ursprüngliche Befehl, und alles wird auseinanderfallen.

Antwort2

Aliase sind nur einfache Ersetzungen. Wenn Sie etwas Ausgefalleneres tun möchten, z. B. eine Nachricht drucken, bevor der Befehl ausgeführt wird, benötigen Sie etwas Mächtigeres: eine Funktion. Wenn die Definition wie eine Aliasdefinition aussehen soll, können Sie eine Funktion definieren, die eine Funktion definiert.

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'

Antwort3

POSIX erfordert diesetBefehldiese Möglichkeit zu haben

-x

   Die Shell soll für jeden Befehl eine Ablaufverfolgung in die Standardfehlerausgabe schreiben, nachdem sie den Befehl erweitert und bevor sie ihn ausführt. Es ist nicht angegeben, ob der Befehl, der die Ablaufverfolgung deaktiviert, verfolgt wird.

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

Sie können also einfach set -xoder set -o xtraceauf allen kompatiblen Shells verwenden. In Bash können Sie Folgendes auf der Manpage sehen:

-x

   Zeigen Sie nach der Erweiterung jedes einfachen Befehls (für Befehl, Case-Befehl, Select-Befehl oder Arithmetik für Befehl) den erweiterten Wert von PS4 an, gefolgt vom Befehl und seinen erweiterten Argumenten oder der zugehörigen Wortliste.

xtrace

   Gleich wie -x.

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

zsh hat auch eine ähnliche Option für dieseteingebaut

XTRACE( -x, ksh: -x)

   Drucken Sie Befehle und ihre Argumente, während sie ausgeführt werden.

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

Sie können die -xOption auch beim Ausführen von Skripten oder Befehlen angeben

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

Beachten Sie, dass dadurch auch die Befehle erweitert werden, die vor und nach jeder Eingabeaufforderung ausgeführt werden. Dies ist in vielen Situationen möglicherweise nicht wünschenswert, z. B. wenn Sie gitVariablen in Ihrer PS1 verwenden. In meiner sauberen Ubuntu-VM wird nur der laufende Befehl ausgedruckt

Siehe auchWas macht set -xdas?

Eine weitere Option ist set -voder set -o verbose, die die Variablen vor dem Drucken nicht erweitert.

Antwort4

Diese Art von Hilfe ist in Bash standardmäßig nicht verfügbar.

Die beiden zugehörigen Funktionen, die standardmäßig verfügbar sind, sind:

  • shopt -s histverify

Wenn diese Option gesetzt ist und readline verwendet wird, werden die Ergebnisse der Verlaufsersetzung nicht sofort an den Shell-Parser übergeben. Stattdessen wird die resultierende Zeile in den Readline-Bearbeitungspuffer geladen, sodass weitere Änderungen möglich sind.

Dies betrifft den Teil einer Aktion, bei dem Entergedrückt wird, aber nur mit einer Verlaufserweiterung in der Befehlszeile. Beispiel:

$ 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!! 
  • Zeile lesenshell-expand-line

Shell-Expand-Line (MCe)

Erweitern Sie die Zeile wie die Shell. Dies führt eine Alias- und Verlaufserweiterung sowie alle Shell-Worterweiterungen durch. Eine Beschreibung der Verlaufserweiterung finden Sie weiter unten unter VERLAUFSERWEITERUNG.

Das ist genau das, was Sie fordern, aber der Schlüssel zum Erfolg ist Ctrl- Alt-e

Mir ist leider keine Lösung bekannt, die mit „enter“ und „executes“ funktioniert shell-expand-line.

verwandte Informationen