Хорошо иметь последний неправильный комментарий, чтобы исправить его, но вскоре после этого он становится потенциально запутанным мусором.
Мой подход состоит из двух этапов: хранить команды, которые терпят неудачу, когда они делают, и удалять их через некоторое время.
Сохраните команды, которые терпят неудачу, когда они делают:
error_handler() {
FAILED_COMMANDS="$(history | tail -1l | cut -c -5) $FAILED_COMMANDS"
}
trap error_handler ERR
trap command signals
выполняется, command
когда один из signals
"поднят".
$(command)
, выполняет command
и захватывает его вывод.
При сбое команды этот фрагмент кода фиксирует номер истории последней команды, сохраненной в истории , и сохраняет ее в переменной для последующего удаления.
Простой, но работает неправильно с HISTCONTROL
и HISTIGNORE
- когда команда не сохраняется в истории из-за одной из переменных, номер истории последней команды, сохраненной в истории, равен номеру предыдущей команды; поэтому, если неправильная команда не сохранена в истории, предыдущая команда будет удалена.
Чуть более сложная версия, которая корректно работает в таком случае:
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
Удалить сохраненные команды через некоторое время:
exit_handler() {
for i in $(echo $FAILED_COMMANDS | tr ' ' '\n' | uniq)
do
history -d $i
done
FAILED_COMMANDS=
}
trap exit_handler EXIT
Объяснение:
При выходе из Bash для каждого уникального номера истории удаляйте соответствующую запись истории,
затем снимите флажок, FAILED_COMMANDS
чтобы не удалять команды, унаследовавшие номера истории от уже удаленных команд.
Если вы уверены, что в нем FAILED_COMMANDS
не будет дубликатов, вы можете просто перебрать его
(т.е. записать for i in $FAILED_COMMANDS
). Однако, если вы ожидаете, что он не будет отсортирован от наибольшего к наименьшему (в данном случае это всегда так), замените его uniq
на sort -rnu
.
Номера истории в FAILED_COMMANDS
должны быть уникальными и сортироваться от наибольшего к наименьшему, потому что при удалении записи номера следующих команд смещаются, т.е. при выдаче history -d 2
третья запись становится второй, четвертая становится третьей и т. д.
Из-за этого при использовании этого кода вы не можете вручную вызвать, history -d <n>
где n
меньше или равно наибольшему числу, хранящемуся в,FAILED_COMMANDS
и ожидать, что код будет работать должным образом.
Это, вероятно , хорошая идея , чтобы зацепить exit_handler
на EXIT
, но вы также можете позвонить в любое время его раньше.