![我可以仅在使用通配符时使“rm”交互吗? (在 bash 或 zsh 或两者中)](https://linux22.com/image/25468/%E6%88%91%E5%8F%AF%E4%BB%A5%E4%BB%85%E5%9C%A8%E4%BD%BF%E7%94%A8%E9%80%9A%E9%85%8D%E7%AC%A6%E6%97%B6%E4%BD%BF%E2%80%9Crm%E2%80%9D%E4%BA%A4%E4%BA%92%E5%90%97%EF%BC%9F%20%EF%BC%88%E5%9C%A8%20bash%20%E6%88%96%20zsh%20%E6%88%96%E4%B8%A4%E8%80%85%E4%B8%AD%EF%BC%89.png)
每当我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
}