zsh history:注释掉危险的命令:`#`

Modified on: Sat, 30 Jun 2018 07:15:00 +0800

多年前在我的相关帖子中,我发现了解决方法如何注释掉bash历史记录中保存的“危险”命令,这样我就不会意外地执行它们。

zsh中实现相同的最佳解决方案是什么?

zsh是否提供了一些我可以用于此目的的功能?
我假设,zsh beieng更灵活,在zsh中应该更容易。

作为参考,这是我在bash中使用的(根据StéphaneChazelas的接受答案):

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
}

更新:

虽然接受的解决方案有效,但它有不良副作用。特别是,zshrc中指定的以下历史记录选项现在被忽略

setopt histignorespace
setopt histreduceblanks

如何让它们再次运作?

最佳答案

当然,使用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选项集。

作者:thrig

相关问答

添加新评论