Você pode fazer algo como:
fixhist() {
local cmd histnum
cmd=$(HISTTIMEFORMAT=/ history 1)
histnum=$((${cmd%%[*/]*}))
cmd=${cmd#*/} # remove the histnum
case $cmd in
(rm\ *|mv\ *|...)
history -d "$histnum" # delete
history -s "#$cmd" # add back with a #
esac
}
PROMPT_COMMAND=fixhist
A idéia é que, antes de cada prompt, verificamos a última entrada do histórico ( history 1
) e se é uma das perigosas , nós a deletamos ( history -d
) e a adicionamos de volta com um #
com history -s
.
(obviamente, você precisa remover sua configuração HISTIGNORE
).
Um efeito colateral indesejado disso é que ele altera o tempo do histórico dos comandos rm
, mv
...
Para corrigir isso, uma alternativa poderia ser:
fixhist() {
local cmd time histnum
cmd=$(HISTTIMEFORMAT='<%s>' history 1)
histnum=$((${cmd%%[<*]*}))
time=${cmd%%>*}
time=${time#*<}
cmd=${cmd#*>}
case $cmd in
(rm\ *|mv\ *|...)
history -d "$histnum" # delete
HISTFILE=/dev/stdin history -r <<EOF
#$time
#$cmd
EOF
esac
}
PROMPT_COMMAND=fixhist
Desta vez, registramos a hora do último histórico e, para adicionar de volta a linha do histórico, usamos history -r
de um arquivo temporário (o documento do here) que inclui o timestamp.
Você deseja que o fixhist
seja executado antes do seu history -a; history -c; history -r
. Infelizmente, a versão atual de bash
tem um erro em que history -a
não salva a linha extra que adicionamos. Uma solução é escrevê-lo:
fixhist() {
local cmd time histnum
cmd=$(HISTTIMEFORMAT='<%s>' history 1)
histnum=$((${cmd%%[<*]*}))
time=${cmd%%>*}
time=${time#*<}
cmd=${cmd#*>}
case $cmd in
(rm\ *|mv\ *|...)
history -d "$histnum" # delete
history -a
[ -f "$HISTFILE" ] && printf '#%s\n' "$time" "$cmd" >> "$HISTFILE";;
(*)
history -a
esac
history -c
history -r
}
PROMPT_COMMAND=fixhist
Isso é para acrescentar o comando comentado ao HISTFILE em vez de deixar history -a
fazer isso.