
В моемсвязанный постМного лет назад я нашел решение, как закомментировать «опасные» команды, сохраненные в истории bash, чтобы не выполнить их случайно.
Какое решение было бы наилучшим для реализации того же самого zsh
?
Предоставляет ли zsh
некоторые функции, которые я мог бы использовать для этой цели? Я предполагаю, что, zsh
будучи более гибким, это должно быть проще в zsh
.
Для справки, вот что я использовал bash
(на основе принятого ответа Стефана Шазеласа):
fixhist() {
local cmd time histnum
cmd=$(HISTTIMEFORMAT='<%s>' history 1)
histnum=$((${cmd%%[<*]*}))
time=${cmd%%>*}
time=${time#*<}
cmd=${cmd#*>}
case $cmd in
(cp\ *|mv\ *|rm\ *|cat\ *\>*|pv\ *|dd\ *)
history -d "$histnum" # delete
history -a
[ -f "$HISTFILE" ] && printf '#%s\n' "$time" " $cmd" >> "$HISTFILE";;
(*)
history -a
esac
history -c
history -r
}
ОБНОВЛЕНИЕ 2022-09-05:
Принятое решение работает, но имеет непреднамеренный побочный эффект. Оно портит insert-last-word
привязку клавиш. Вот короткая иллюстрация:
Я использую одну из своих «опасных» команд:
rm zz
он был добавлен в историю с комментарием (по желанию):
history
...
# rm zz
Давайте просто добавим еще одну команду в историю.
echo foo
И теперь, когда я хочу просмотреть историю с помощью Alt+ ., я получаю следующие результаты:
echo <Alt> + .
foo
history
# rm zz
вместо того, чтобы быть предложенным zz
, мне предлагается вся прокомментированная команда # rm zz
.
Как я могу это исправить ?
решение1
Конечно, используйте zshaddhistory
функцию перехвата и отключите обычную обработку истории.
function zshaddhistory() {
# defang naughty commands; the entire history entry is in $1
if [[ $1 =~ "cp\ *|mv\ *|rm\ *|cat\ *\>|pv\ *|dd\ *" ]]; then
1="# $1"
fi
# write to usual history location
print -sr -- ${1%%$'\n'}
# do not save the history line. if you have a chain of zshaddhistory
# hook functions, this may be more complicated to manage, depending
# on what those other hooks do (man zshall | less -p zshaddhistory)
return 1
}
Протестировано таким образом на zsh 5.0.8
% exec zsh
% echo good
good
% echo bad; rm /etc
bad
rm: /etc: Operation not permitted
% history | tail -4
299 exec zsh
300 echo good
301 # echo bad; rm /etc
302 history | tail -4
%
Похоже, это работает extendedhistory
и с набором опций.
решение2
Следующая функция основана на функции thrig и исправляет histignorespace
:
function zshaddhistory() {
if [[ $1 =~ "^ " ]]; then
return 0
elif [[ $1 =~ "cp\ *|mv\ *|rm\ *|cat\ *\>|pv\ *|dd\ *" ]]; then
1="# $1"
fi
# write to usual history location
print -sr -- ${1%%$'\n'}
# do not save the history line. if you have a chain of zshaddhistory
# hook functions, this may be more complicated to manage, depending
# on what those other hooks do (man zshall | less -p zshaddhistory)
return 1
}