如何掌握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.