请考虑以下命令:
find . -type f -name '*.*' -exec mv '{}' '{}_foo' \;
在这种情况下如何find
防止无限循环?
一方面,我相信 find不像 shell glob那样工作,即它不会获取所有*.jpg
文件的列表,在内部存储该列表,然后处理列表条目。相反,它让文件从底层 O/S “增量”处理,并在它知道后立即处理每个文件(让我们忽略可能发生的一定数量的缓冲,因为这与问题无关)。毕竟,据我所知,这是find
在目录中包含大量文件的全局全局的主要优势。
如果这是真的,我想了解 find 如何防止无限循环。在上面的示例中,1.jpg
将重命名为1.jpg_foo
. 从 StackOverflow 和其他地方的讨论中,我知道重命名可能会导致文件(名称)在目录文件列表中占据不同的位置,因此 find 很可能再次遇到该文件,再次将其重命名为(to 1.jpg_foo_foo
),等等上。
显然,这不会发生。
在单个目录中,它可能就像在处理之前读取整个文件列表一样简单(并
strace
使其看起来就像发生了什么):(为便于阅读而对输出进行了删节)
但是,一般来说,
find
根本不会阻止任何循环。如果将文件移动到子目录,则会发生多次:这会导致
sub/sub/sub/sub/file_foo_foo_foo_foo
诸如此类的事情。(-depth
在这种情况下可能会有所帮助)。最好一开始就避免任何可能的冲突,而不是盲目地依赖
find
使用一些不存在的魔法。您在编辑之前的问题是一个很好的解决方案,因为它根本不匹配已经重命名的文件。即使在没有严格要求的情况下,也可以明确说明文件不能也不应该被处理两次。我们在
jpg
这里重命名文件而不是foo
文件。此外,即使
find
在一次调用中会阻止两次处理文件,脚本作为一个整体也会重新运行并且 find 会再次运行,因此无论哪种方式,您都需要采取适当的保护措施。