我们的网络服务器最初是由另一家公司维护的。他们编写了一个简短的脚本来清理缓存文件。他们的文件有几行内容如下:
/usr/bin/find /var/www/cache/blah/ |xargs /bin/rm -f >/dev/null 2>&1
他们有什么理由不能直接写:
/bin/rm -f /var/www/cache/blah/*
删除文件?当您需要特定标准时,我可以看到使用find
,但在这种情况下我似乎找不到。
答案1
我可以考虑他们使用find
+的一些原因xargs
:
处理缓存文件过多的情况,如果只运行一个
rm
命令会导致错误。通配符
*
不会扩展隐藏文件。递归地工作。
但是这个find
+xargs
效率不高,因为当他们没有添加任何过滤器时,find
结果将包含目录和文件。在目录上运行/bin/rm -f
会导致错误,这就是stderr
和stdout
被重定向到/dev/null
.对于名称包含特殊字符的文件,该命令也会失败。
改进的解决方案可以是:
find /var/www/cache/blah -type f -exec rm -f -- {} +
这是更高效的,用 POSIXly 进行所有工作find
,最小化分叉rm
。
答案2
命令行的行为有一些差异:
- 命令
find
行会删除文件在子目录中递归,rm
命令行不会。你需要考虑是否要递归。 - 如果可能的话,命令
find
行将删除所有文件。命令rm
行可能会跳过文件基于 shell 的设置,例如GLOBIGNORE
.您需要考虑路径名扩展中是否可能会意外忽略某些文件名。 - 命令
find
行将成功处理任意数量的文件。命令rm
行可能会失败如果路径名扩展创建了命令行那是太长(大于系统支持的大小)。有些系统对此有限制。您需要考虑可能需要删除多少文件。 - 命令
find
行忽略所有输出消息(使用重定向到>/dev/null
)。命令rm
行打印输出消息。您需要考虑消息会发生什么。
如果这些差异对你来说不重要,那么/bin/rm -f /var/www/cache/blah/*
它们就会对你有用。
如果只删除文件,保留目录,我实际上会使用
/usr/bin/find /var/www/cache/blah/ -not -type d -exec /bin/rm -f -- {} + >/dev/null 2>&1
或者
/usr/bin/find /var/www/cache/blah/ -type f -exec /bin/rm -f -- {} + >/dev/null 2>&1
无论适合您的目的,两者都有优点和缺点。
-exec command {} +
工作方式与 类似xargs
,但效率稍高一些。如果其中一个文件--
名rm
以-
.此外,xargs
其使用方式对文件名做出了太多假设。像空格这样的特殊字符实际上会破坏 的简单调用xargs
。find ... -print0 | xargs -0
需要类似的东西,然后find -exec command {} +
就简单多了。
答案3
其他答案忽略了三点:
永远不要这样做:
/usr/bin/find /var/www/cache/blah/ |xargs /bin/rm -f >/dev/null 2>&1
因为当您的文件中包含空格时,rm
将尝试删除两个文件,并产生令人惊讶的结果。
如果您坚持这样做,假设您正在使用 GNUfind
和xargs
,您需要:
/usr/bin/find /var/www/cache/blah/ -print0 | xargs -0 /bin/rm -f >/dev/null 2>&1
其中零终止文件(并且期望 xargs 中的零终止)。
其次,您是否尝试删除目录?如果没有,您需要“-type f”。如果是这样,您需要“rm -rf”,因为rm
没有“rm -rf”-r
将不会删除目录。
但最重要的是,OP 要求更短的方法,而答案似乎更长。怎么样:
/usr/bin/find /var/www/cache/blah/ -delete
我相信-delete
这是一个 GNU 扩展,所以检查你的版本是否find
支持它。