如何掌握UNIX find命令?


11

我认为我在使用find方面相当先进,但是每次使用它时,我都无法记住关闭-exec选项的方法。每次使用时,我都会花费大量时间阅读。我只是没有充分使用它还是对自己期望过高?让我们从一个让我感到沮丧的典型例子开始。

目录结构包含具有所有不正确权限的文件,隐藏文件,符号链接等。我想将所有权更改为合理的值

find . -type f -exec chown username {} \;
find . -type d -exec chown username {} \;
find . -type d -exec chgrp usergroup {} \;
find . -type f -exec chgrp usergroup {} \;

(请原谅我,如果结尾是倒退的……一个小时前我看了一下,但仍然不确定)

但是由于安装,符号链接等原因,我不敢运行它。我知道-xdev会放弃跨分区,但是我不确定位于符号链接目录中的文件会发生什么情况。

那么,如何掌握这种可以杀死重要文件的野兽呢?

更新修剪以下最佳建议并进行总结:

  1. 将练习目录链接并挂接到其他练习目录。
  2. 使用xargs而不是非直观的exec命令。
  3. 使用-exec echo {}可以保持健康和安全
  4. 半冒号很特殊,您正在转义,因此转义符是第一个
  5. -or命令可以帮助您组合选择条件。

我对print0有点困惑,但是xargs一直是我尝试避免的乍一看并不容易理解的地方。


1
我也不记得了,所以我只是将其传送到xargs中。
— 谐振器

2
当您对构建正确的命令感到满意时,请考虑使用+而不是\;运行它。使用+可以更快地运行,因为exec命令的调用频率将大大降低。
— wzzrd 2009年

wzzrd,关于使用+而不是\的重要提示;
— 丹尼尔·劳森,2009年

Answers:


19

好吧,就-exec语法而言,您可以像很多人一样,放弃并使用xargs:

find . -type f | xargs chown username

(或带有空格和其他废话的文件的安全版本)

find . -type f -print0 | xargs -0 chown username

或者,要想记住与分号有关的正确操作,您需要深入了解一下您正在使用分号来终止-exec正在运行的命令,并且必须对分号进行转义,因为它具有特殊的含义意思是bash。这就是为什么它是反斜杠分号。您似乎可以{}替代部分。

至于杀死文件等,如果您正在运行某些大而危险的内容,例如:

find . -type f -exec echo chown username {} \;

并查看结果。基本上,这是一个“空运行”,您会看到如果允许的话它将运行的命令。绝对是个好习惯。不会帮助您解决此.*问题,但是您知道现在不这样做。:)


1
+!进行“回声”练习空转。我总是用它来
— 做个

3

我很惊讶没有人提到以下选项:

find . -type f -ok chown username {} \;

该语法将在执行命令之前确认该命令。如果您希望匹配的文件数量相对较少,则效果最佳,因为它会提示每个文件。

提到了一些答案xargs,但是对于GNU,这也是不必要的:

find . -type f -exec chown username {} \+

请注意,通常不需要转义+,但是无论如何要养成这样做的习惯是很好的。


您能解释加号的性质吗?它到底在做什么?是shell处理它还是命令。我想我将下载gnu-find的源代码,因为这是一个有趣的话题。
— ojblass

查找正在处理它。阅读man find以了解有关该选项的更多信息。
— 卡米尔·基西尔

3

这就是man的目的: 可能很难记住事情,这就是* nix命令包含手册页的原因。您可以随时查看手册页的ACTION部分,以获取有关语法的提示:man find。尽管手册页可能看起来并不友好,但是一旦您精通阅读手册,它们就会非常方便。

做一个前端或包装器: 当我想更好地使用GNU find时,我写了一个GUI前端for find,它使用python,glade和pygtk生成find命令。如果想真正了解它,这是一个很好的练习。

拥有一个练习目录: 最后,我的主目录中始终有一个“废品”目录,用于在诸如“回声”之类的东西无法剪切时播放功能强大的命令。您可以使用Shell扩展来快速生成一堆文件,例如:

for i in {1..100}; do touch "$i"; done

我从未考虑过一个奇怪的练习目录。
— ojblass

1

您还可以将查找表达式与'-and'和'-or'运算符结合使用。-并且是隐式的:

find . -type f -name "plainfile" ...

是相同的

find . -type f -and -name "plainfile" ...

or运算符可以将您的4个命令列表减少为2:

find . -type d -or -type f ...

最后,与查找无关,但chown也可以设置组。因此,还要处理名称中的空格,我们最终得到:

find . -type d -or -type f -exec chown username:usergroup '{}' \;

与-或业务找到什么。[Sic]
— ojblass

@ojblass:find使用'and'或'or'组合表达式,默认情况下,如果未指定'-and'或'-or',则隐式使用'-and'。所以类型'find -type d -type f'将找不到任何东西,因为目录和文件都不是。
— 史蒂夫·弗利

0

关闭时,我只是想使用;例如使用许多编程语言然后转义。只要记住,这是需要逃脱的,它很容易就传给您。


0

根据您使用的查找版本的不同,可能有不同的选项可以为您提供帮助。GNU find可能是最强大的,这可能会帮助您解决第二个(暗示的)问题

例如,默认行为是不取消引用符号链接,但是您可以覆盖它;和-mount选项停止查找跨挂载点

查看您的本地手册页


0

有人会说 xargs选项比-exec选项更快,因为它不会为每个文件执行一次命令,但是我不担心这件事,除了需要大量时间的大量工作之外。

就我个人而言,我通常只是在没有exec的情况下运行find

find /path/to/dir -name whatever

确保输出看起来正确,然后在该列表上运行我的命令。

chown user:group `find /path/to/dir -name whatever`

如何“不”做事情的完美例子。带空格的文件名。
— 伊恩·凯灵

是的,这是一个潜在的问题,我也许应该承认。但是我的意思是要在执行任何操作之前先读取查找输出,在此之前您会发现空格或其他文件名异常。
— theotherreceive

0

对于某些shell(不是bash),请转义{}以获取正确的行为。

\{\} or '{}'

查找手册非常适合掌握查找。


不,你不;find与{}一样可以正常运行。它们是find命令的一部分:它们是被find命令的结果替换的令牌。它们仅在定义函数或调用变量时在bash中表示含义,因此您可以像在原始问题中一样使用它们。
— wzzrd 2009年

它来自手册页。我更新说它不适用于bash。
— 伊恩·凯灵

0

在执行此类操作之前,请确保针对其运行此命令的目录与/ usr或/ etc不在同一文件系统中。(否则,如果我在主目录中有到/ etc / passwd或/ bin / sh的硬链接,您只是给了我这些文件的所有权,并且附带的一点是,我现在拥有该机器)。

如果您要遍历目录并整理所有文件/目录,则简单

chown -Rh用户:usergroup用户/

会做的。请确保您使用-h或CHOWN将遵循符号链接。


我认为这不是跨平台的。如我的练习环境所示,也无法处理247K的文件。我不知道为什么。
— ojblass

我认为您发现的错误比发现的跨平台问题还多。哪个版本失败,退出状态是什么?据我所知,它最早起源于早期的bsd版本。它肯定在sunos 5.3和ultrix和irix中。在失败之前需要处理多少个?
— 克里斯

没错,它可以在AIX 5.3,AIX 5.2上运行,但不能在AIX 4.3,NCR,HP 11,HP 10.20或我的DSL发行版上运行。在所有情况下,它似乎在6万个文件或附近失败。
— ojblass
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.