Es ist gut, den letzten falschen Kommentar zu haben, um ihn zu korrigieren, aber kurz danach wird es möglicherweise zu einem verwirrenden Müll.
Mein Ansatz besteht aus zwei Schritten: Speichern Sie fehlgeschlagene Befehle und entfernen Sie sie später.
Speichern Sie Befehle, bei denen ein Fehler auftritt:
error_handler() {
FAILED_COMMANDS="$(history | tail -1l | cut -c -5) $FAILED_COMMANDS"
}
trap error_handler ERR
trap command signalswird ausgeführt, commandwenn einer von signals"ausgelöst" wird.
$(command), führt das aus commandund erfasst seine Ausgabe.
Wenn der Befehl fehlschlägt, erfasst dieses Codefragment die Verlaufsnummer des zuletzt im Verlauf gespeicherten Befehls und speichert sie in einer Variablen zum späteren Löschen.
Einfach, funktioniert aber nicht richtig mit HISTCONTROLund HISTIGNORE- Wenn der Befehl aufgrund einer der Variablen nicht im Verlauf gespeichert wird, ist die Verlaufsnummer des zuletzt im Verlauf gespeicherten Befehls die Nummer des vorherigen Befehls. Wenn also ein falscher Befehl nicht im Verlauf gespeichert wird, wird der vorherige Befehl gelöscht.
Etwas kompliziertere Version, die in diesem Fall korrekt funktioniert:
debug_handler() {
LAST_COMMAND=$BASH_COMMAND;
}
error_handler() {
local LAST_HISTORY_ENTRY=$(history | tail -1l)
# if last command is in history (HISTCONTROL, HISTIGNORE)...
if [ "$LAST_COMMAND" == "$(cut -d ' ' -f 2- <<< $LAST_HISTORY_ENTRY)" ]
then
# ...prepend it's history number into FAILED_COMMANDS,
# marking the command for deletion.
FAILED_COMMANDS="$(cut -d ' ' -f 1 <<< $LAST_HISTORY_ENTRY) $FAILED_COMMANDS"
fi
}
trap error_handler ERR
trap debug_handler DEBUG
Gespeicherte Befehle später entfernen:
exit_handler() {
for i in $(echo $FAILED_COMMANDS | tr ' ' '\n' | uniq)
do
history -d $i
done
FAILED_COMMANDS=
}
trap exit_handler EXIT
Erläuterung:
Entfernen Sie beim Verlassen von Bash für jede eindeutige Verlaufsnummer den entsprechenden Verlaufseintrag. Deaktivieren Sie
dann das Kontrollkästchen, FAILED_COMMANDSum keine Befehle zu entfernen, die Verlaufsnummern von bereits gelöschten Befehlen übernommen haben.
Wenn Sie sicher sind, dass FAILED_COMMANDSkeine Duplikate vorhanden sind, können Sie einfach darüber iterieren
(dh schreiben for i in $FAILED_COMMANDS). Wenn Sie jedoch erwarten, dass es nicht vom größten zum kleinsten sortiert wird (in diesem Fall immer), ersetzen Sie es uniqdurch sort -rnu.
Verlaufsnummern in FAILED_COMMANDSmüssen eindeutig sein und vom größten zum kleinsten sortiert werden, da beim Löschen von Einträgen die Nummern der nächsten Befehle verschoben werden - d. H. Wenn Sie ausstellen history -d 2, wird der dritte Eintrag zum zweiten, der vierte zum dritten usw.
Aus diesem Grund können Sie bei Verwendung dieses Codes nicht manuell anrufen, history -d <n>
wo neine kleinere oder gleich große gespeicherte Nummer vorhanden ist,FAILED_COMMANDS
und erwarten, dass der Code ordnungsgemäß funktioniert.
Es ist wahrscheinlich eine gute Idee , Haken exit_handleran EXIT, aber man kann es auch früher jederzeit anrufen.