如何防止rm命令报告文件未找到?

222

我在BASH脚本中使用rm删除许多文件。有时文件不存在,因此它会报告很多错误。我不需要这个消息。我已经搜索了man页面,想找到一个可以让rm静默的命令,但是我找到的唯一选项是-f,从描述“忽略不存在的文件,永远不提示”来看,似乎是正确的选择,但是名称似乎不太合适,所以我担心它可能会产生意外后果。

  • -f选项是否是使rm静音的正确方法?为什么它不叫做-q
  • 此选项是否还有其他作用?
答案:
  1. -f选项是使rm静默的正确方法,尽管该选项被描述为"忽略不存在的文件,永远不提示",但它也可以在删除文件时强制进行操作,即使没有写权限或存在只读文件,也可以删除。它被称为-f而不是-q,可能是因为其默认行为是提示用户确认是否要删除每个文件,而-f选项禁用了这个询问,因此被称为“强制”选项。
  2. 除了忽略不存在的文件和禁止询问外,-f选项没有其他作用。注意:这是一个非常危险的选项,因为它可以删除任何文件而不进行确认,所以要谨慎使用。

5
你不想使用 "-f",它会删除被标记为只读的文件。 - pizza
如果你将它们标记为只读(_badly_),那么只有 @pizza 才能删除它们。如果你正确使用权限系统,即使使用 -frm 也无法删除只读文件;而且如果你没有以操作系统实际执行的方式进行操作,那么它真的是只读的吗? - Charles Duffy
6个回答

268

-f 的主要用途是强制删除在使用 rm 时无法被删除的文件(作为一个特例,它会“删除”不存在的文件,从而抑制错误提示)。

你也可以通过重定向错误消息来达到同样的效果。

$ rm file.txt 2> /dev/null

(或者您的操作系统相应的等价物)。您可以在调用rm后立即检查$?的值,以查看文件是否被实际删除。

(or your operating system's equivalent). 指的是您需要使用您操作系统中对应的命令。您可以在调用rm后立即检查$?的值,以查看文件是否被实际删除。


3
--f 可以在 GNU Coreutils 的 rm 命令中使用,但这仅仅因为它恰好是 --force 的唯一缩写。缩写形式 -f 更加清晰易懂且更具可移植性。 - Keith Thompson
1
我甚至不确定自己是否意识到了这一点。这里的“--f”只是“-f”的拼写错误。 - chepner
6
2> 中的数字 2 表示标准错误输出流(STDERR)。它是一个 Linux 命令行中用于将命令或程序的错误信息从屏幕输出重定向到文件或另一个程序的符号。 - Dan
@Maverick 它将发送到stderr的任何消息重定向到/dev/null,而不是将它们发送到终端。 - Benjamin Nolan
3
它不会在终端输出错误,但它会像致命错误一样停止代码执行,因此它实际上并没有解决问题... - Ido
@Ido 这不是 rm 的问题。rm 会在退出时删除它可以删除的文件(如果您将现有和不存在的文件混合指定为参数),然后以非零退出代码退出。如果您使用 set -e 运行脚本(我不建议这样做),则需要使用类似 if rm ...; then ...; fi 的东西来“保护”命令,以便检测是否出现错误而不会导致 shell 本身退出。 - chepner

98

是的,-f 是最适合此操作的选项。


有些系统会在你使用-f直到你使用反斜杠时提示你房间。 - vimdude
13
@vimdude:这不是“某些系统”的问题;这种行为表明您有一个shell函数或别名将rm映射到rm -i - Keith Thompson

36

-f是正确的标志,但针对的是测试操作符,而不是rm

[ -f "$THEFILE" ] && rm "$THEFILE"

这确保文件存在且是一个常规文件(不是目录、设备节点等等...)


7
然而,这存在竞态条件,并且不应在生产脚本中使用。 - tripleee
我相信 @tripleee 指出的是 "-f" 测试和文件删除可以以任何顺序完成。另一种方法是:if [ -f "$THEFILE" ]; then rm "$THEFILE"; fi,这使得测试和文件删除步骤明确地按顺序执行。 - robla
3
@robla 那段代码使用更冗长的语法做了完全相同的事情... && != & ... 测试将始终在 rm 之前发生,但是一个单独的进程在 rm 运行之前(在测试后的 shell 代码被解释时)可能会删除它,尽管这种情况非常不太可能。 - technosaurus
技术恐龙 - 哎呀,你说得对。你认为@mmlac的问题最好的答案是什么? - robla
@robla,这个问题目前有两个答案,每个答案都有超过40个赞,你认为这两个答案不可接受吗?我的投票支持“简单地使用rm -f”,因为丢弃错误消息可能会掩盖其他错误。这个答案是误导性的,暗示使用rm -f是有问题的,而且某人犯了一个错误并打算使用test -f - tripleee
3
仅仅是为了确认一下,竞态条件是指在testrm之间会有某些东西可能会移除该文件。这里没有办法让rmtest之前执行。在并发编程中,先看后跳是一个常见的错误——当你真正进行跳跃时,你不能再信任“看”的结果。解决这个问题的方法是使用锁或原子操作。这也正是为什么你需要使用rm -f的原因,它就是后者的一个例子。 - tripleee

20

\rm -f file 永远不会报告找不到。


7
-r是不必要且危险的。 - mahemoff
1
我假设了许多文件或目录。重新阅读用户的请求,你是对的,他只要求文件。所以我更正了我的答案。 - vimdude
反斜杠在rm前面是做什么的??请大家帮忙回答一下。在Windows Cygwin的make版本4.1中,无法处理\rm,而3.75却可以正常工作。 - Ayman Salah
3
在这种情况下,反斜杠会转义任何包装真正的 rm 命令或别名的函数(在20世纪90年代早期的一些网站上流行,以防止初学者删除文件并打电话给系统管理员找回它们)。 - tripleee
谢谢 - 这解决了我的问题。显然,使用退出代码可以使用 && 进行链接,而没有 -f 时,一旦找不到文件就会中断。 - Igor

9

rm -f 命令而言,“做其他任何事情”,它会在 rm 命令需要确认时强制执行静默删除操作(-f--force 的缩写)。例如,当您试图从可写目录中删除您没有写入权限的文件时。


-11

我在cshell中遇到了同样的问题。我唯一的解决办法是在我的脚本中,在“rm”之前创建一个匹配模式的虚拟文件。


8
那真的是唯一的解决方案吗?您尝试过rm -frm 文件名 >&/dev/null吗? - Keith Thompson
也许这不是唯一的解决方案,但它是明智的、易读的,并且没有副作用。 - commonpike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接