Добре мати останній невірний коментар, щоб виправити його, але незабаром після цього сміття стає потенційно заплутаним.
Мій підхід є двокроковим: зберігайте команди, які виходять з ладу, і видаляйте їх десь пізніше.
Зберігайте команди, які не спрацьовують:
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
.
Числа історії в In FAILED_COMMANDS
повинні бути унікальними і відсортовані від найбільшого до найменшого, тому що при видаленні запису номери наступних команд зміщуються - тобто. коли ви видаєте history -d 2
, 3-й запис стає другим, 4-й стає 3-м тощо.
Через це, використовуючи цей код, ви не можете вручну зателефонувати history -d <n>
там, де n
менше або дорівнює найбільшій кількості, що зберігається,FAILED_COMMANDS
і очікувати, що код справно працює.
Це, ймовірно , хороша ідея , щоб зачепити exit_handler
на EXIT
, але ви також можете зателефонувати в будь-який час його раніше.