我正在编写一个makefile,它将在编译结束时清除一些无用的文件。如果已经制定了目标,则它当然会跳过该目标,并且可能没有有用的文件。因此,如果执行此操作:

rm lexer.ml interpparse.ml interpparse.mli


由于其中一个文件不存在,我可能会收到错误消息。有什么办法让rm忽略这些文件吗?

在阅读手册页时,我看到以下选项:

 -f          Attempt to remove the files without prompting for confirma-
             tion, regardless of the file's permissions.  If the file does
             not exist, do not display a diagnostic message or modify the
             exit status to reflect an error.  The -f option overrides any
             previous -i options.


那听起来几乎是我想要的,但是我不确定权限部分。有办法吗?

评论

您在沙盒中尝试过RM吗?看起来-f完全可以满足您的要求,而不管这些问题如何。

如果权限不允许,rm将使用-f选项继续尝试将其删除。它会失败。它不会告诉您它失败了。如果文件名是变量或全局变量,则很有用。

仅出于完整性考虑:rm --interactive = never的行为类似于rm -f,但它确实返回错误退出状态。请参阅此处以了解更多详细信息:unix.stackexchange.com/questions/72864/…

既然您在问题中提到Makefile,我认为@robertLi的答案最合适。以'-'开头是解决此问题的一种方法;其他处理Makefile的人可能会认出它。

#1 楼

-f选项绝对是您要使用的选项。

关于它所指文件权限的确认是这样的:

$ touch myfile    
$ chmod 400 myfile
$ rm myfile       
rm: remove write-protected regular empty file `myfile'?


所以rm如果您尝试删除没有写权限的文件,将会警告您。如果您对目录具有写权限,但是这有点怪异,则允许这样做,这就是为什么rm通常会警告您。

评论


大多数但不是所有系统都会问(我认为)。有些要求-i。

– DaveParillo
09年11月27日在18:11

如果您想要错误消息,而不是错误退出代码,请参见Giel Berkers的答案。我在所有bash脚本中都使用set -e,以便在任何命令给出错误后该脚本退出。我经常希望脚本告诉我rm是否给出错误,但是无论如何还是要继续。继续。

–cledoux
16年6月6日在4:05

#2 楼

另一个解决方案是:https://stackoverflow.com/questions/11231937/bash-ignoring-error-for-a-particular-command

只需在命令后添加OR语句:

rm -rf my/dir || true


这样,当语句#1失败(引发错误)时,运行语句#2,即true

评论


它输出错误并继续执行,这是我的情况所需的。

– worldsayshi
16年2月29日在14:28

或者只是rm -rf my / dir ||:更加简洁(:是true的缩写)

–戈德史密斯
16-10-4在14:55



我认为更好的解决方案。很容易看到发生了什么,以及为什么忽略了结果代码。我喜欢!

–马瓦马滕
17-10-3在14:13

这是使用set -e时防止脚本中断的唯一方法

– dmikam
4月8日下午16:50

#3 楼

我参加聚会很晚,但是我一直都在用。在生成文件中,将-添加到行的开头以忽略该行的返回值。像这样:

-rm lexer.ml interpparse.ml interpparse.mli


评论


但是,这仍然会向控制台输出错误,这会训练您忽略make输出中的错误,这可能不是您想要的。我认为rm -rf是更好的选择。

–戈德史密斯
16-10-4在14:54

@Godsmith我宁愿忽略错误,也不愿强制递归删除。这可能很顽皮。并为makefile特定语法+1

–戴氏
17年12月6日15:06



如果rm -rf可能是“顽皮的”,则意味着您正在版本控制下的目录外部使用make。为什么?

–戈德史密斯
17年12月8日在7:27

请提供文档链接。可以找到此功能的描述。

–乔治·索维托夫(George Sovetov)
18年1月30日在16:50

我认为这是优越的。 -f还跳过交互模式,跳过只读文件等。-但是,此解决方案完全执行OP的要求。

– phil294
18年3月17日在6:39

#4 楼

如果您不想使用-f选项,则可以选择:
rm filethatdoesntexist 2> /dev/null || true

这将防止打印错误。

评论


不幸的是,这仍然会给出错误退出代码。

–肖恩·麦当劳(Shaun McDonald)
13年20月20日17:37

#5 楼

如果您找到某种方式来使文件名具有全局性,则rm不会抱怨找不到匹配项。因此,像lexer.m* interpparse.*之类的东西应该对您有用(当然,请注意不要删除太多内容)。另外,-f是一种完全合理的选择,只要您不希望文件权限可以使您免于删除不想要的文件-如果您不想删除它,请不要放在列表中。

评论


由于存在我不想删除的lexer.mll文件,因此无法进行遍历。感谢您展示为什么-f是合理的。我想在一个错误引导的sudo rm -rf之后,我倾向于过于小心。

–杰森·贝克(Jason Baker)
09年11月27日在16:53

甚至不是限制性更强的lexer.m吗? ...?这将捕获lexer.ml和lexer.mz,但不会捕获lexer.mll或lexer.mla。

– JMD
09年11月27日在16:58

@JMD:我想这取决于您的外壳以及它提供的模式匹配支持。

–尼克·巴斯汀(Nick Bastin)
09年11月29日在0:56

#6 楼

-f选项表示如果某些操作与预期不符,将不会提示您。这并不意味着不会考虑权限。

如果您没有足够的特权来删除文件,则不会删除该文件。

但是,如果您有足够的特权可以更改特权,您的文件将被删除。当您是具有所有者(-r --------)只读权限的文件的所有者时,就是这种情况。作为所有者,您可以chmod u+w,然后将其删除:rm -f将删除该文件。

#7 楼

也许可以帮助类似于以下内容的一行:

touch fakefile.exe fakefile.o && rm *.o *.exe


我知道这不是很聪明,但是确实可以。

#8 楼

另一种选择:

RmIfIsFile() {  for f in "$@"; do [ -f $f ] && rm $f; done; };  RmIfIsFile lexer.ml interpparse.ml interpparse.mli


很糟糕的Makefile无法跨行共享Shell函数定义。

评论


您是否尝试过在行末使用\(反斜杠)以使其在下一行继续?

–一些
2012年7月31日19:35

@some:是的,它们可以分布在多行中,但是要在配方之间共享它们,则必须将定义放入make变量中。

– reinierpost
2012年10月1日13:56

#9 楼

这是我在shell脚本中使用的东西。它隐藏错误消息和错误代码。

rm doesnotexist 2> /dev/null || echo > /dev/null


评论


rm dosnotexist 2&> / dev / null如何

–user8162
19年2月18日在23:07

#10 楼

首先测试文件是否存在,如果存在,然后将其传递给rm。那么rm的错误将是有意义的。 -f或忽略错误消息通常比人们想要的包含更多内容。 -f可能会执行您不希望做的事情。

if [ -f lexer.ml ]; then
  rm lexer.ml
fi


如果要确保存在更多文件,请添加更多测试子句。

#11 楼

您可以在rm之前先触摸文件。
如果不存在,则会创建它们:-)

touch lexer.ml interpparse.ml interpparse.mli
rm lexer.ml interpparse.ml interpparse.mli


#12 楼

编写rm -rf ppp>/dev/null 2>&1
您会收到一条错误消息,如果不是STDERR 2而是STDOUT 1发生错误,则会发生问题。当命令生成的不是错误而是警告时,发生这种情况。
您需要设置过滤器并将其删除信息。但是这种情况很普通。