我可以仅在使用通配符时使“rm”交互吗? (在 bash 或 zsh 或两者中)

我可以仅在使用通配符时使“rm”交互吗? (在 bash 或 zsh 或两者中)

每当我rm使用 shell 通配符一次添加多个项目时,即使模式扩展超出我预期的可能性很小,我总是尝试记住添加-i,但是(当然)我可能会忘记并意外地吹掉一些有用的东西。有些人尝试使用别名来解决这个问题,例如alias rm='rm -i'但我讨厌使用 rm 的想法总是-f互动,因为那样我就会养成一直使用的习惯,这显然会破坏整个目的。

我想做的是rm-i在使用 globbing 时才使用,当然也-f可以覆盖-i,所以我仍然可以用通常的rm -rf junk.

因此rm *blah*确实会如此,rm -i *blah*rm blah会完全按照键入的方式工作。

如果在不同的 shell 中完成此操作的方式存在差异,我将选择一个为 bash 提供方法的答案zsh 超过仅涵盖其中之一的答案。


笔记:我实际上并不相信这一定是个好主意;我只是问是否可以。如果你认为这是一个愚蠢的想法,我会很高兴听到你的观点背后的理由,但是请不要在答案字段中发表此类评论。真正的答案要么告诉我如何做到这一点,要么解释/为什么这是不可能的(或者可能提供另一种方法来获得类似的结果)。但如果你想告诉我为什么这很愚蠢,请发表评论。即使我不同意结论,我也会赞成有理有据的评论。

答案1

这并不容易。问题是当你这样做时:

rm -- *.txt

rm 只看到文件列表,而不是已经由 shell 扩展的通配模式。

你可以做的是(zsh):

alias rm='noglob rm'

这告诉 zsh 在调用 rm 时不应扩展模式。然后您可以将 rm 重新定义为一个函数,该函数本身进行扩展并添加“-i”(如果需要),如下所示:

'rm'() {
  [[ "$*" = *[*[?]* ]] && set -- -i "$@"
  command rm $~@
}

但这种方法的问题是,这个新的“rm”看不到之间的区别

rm *

rm '*'

要删除名为 的文件*,您必须编写它:

rm [*]

答案2

也许 9 年前你问这个问题时情况并非如此,但你现在想要的是 zsh 目前的默认设置。它会注意到您何时要运行rm*在运行之前提示您:

$ rm *
zsh: sure you want to delete all 10 files in /foo/bar [yn]?

还有这些相关的 shell 选项:

RM_STAR_SILENT (-H)

rm *在执行或之前不要查询用户rm path/*

RM_STAR_等待

rm * 如果在执行或 之前查询用户rm path/*,请首先等待十秒钟并忽略此时输入的任何内容。这避免了yes 当人们无意时条件反射地回答查询的问题 。通过扩展*ZLE(带选项卡)中的 ,始终可以避免等待和查询。

答案3

在 bash 中工作,可能在其他 shell 中工作。放置在你的.bashrc

function rm() { 
  while test "${1:0:1}" = "-"; do 
    shift
  done
  if test $# -eq 1; then 
    command rm "$1"
  else 
    command rm -i "$@"
  fi
}

相关内容