运营商
即使所有的测试 发现 提供,我们可能仍然需要一种更好的方式来描述 逻辑关系 在测试之间。 例如,如果我们需要确定目录中的所有文件和子目录是否具有安全权限怎么办? 我们将查找权限不是 0600 的所有文件和权限不是 0700 的目录。幸运的是, 发现 提供了一种使用组合测试的方法 逻辑运算符
创建更复杂的逻辑关系。 为了表达上述测试,我们可以这样做:
[我@linuxbox ~]$ 找到 ~ \( -type f -not -perm 0600 \) -or \( -type d
-不是-perm 0700 \)
[我@linuxbox ~]$ 找到 ~ \( -type f -not -perm 0600 \) -or \( -type d
-不是-perm 0700 \)
哎呀! 那肯定看起来很奇怪。 这都是什么东西? 实际上,一旦您了解它们,操作符并没有那么复杂。 这是清单:
表 17-4:查找逻辑运算符
操作员说明
操作员说明
-和 如果运算符两边的测试都为真,则匹配。 可以缩短为 -a. 请注意,当没有运算符存在时, -和 默认是隐含的。
-要么 如果运算符任一侧的测试为真,则匹配。 可以缩短为 -o.
-没有t 如果运算符后面的测试为假,则匹配。 可以用感叹号 (!) 缩写。
() 将测试和运算符组合在一起以形成更大的表达式。 这用于控制逻辑评估的优先级。 默认情况下, 发现 从左到右评估。 通常需要覆盖默认的评估顺序以获得所需的结果。 即使不需要,有时包含分组字符以提高命令的可读性也很有帮助。 请注意,由于括号字符对 shell 具有特殊含义,因此在命令行上使用它们时必须引用它们,以允许将它们作为参数传递给 发现. 通常反斜杠字符用于转义它们。
有了这个运算符列表,让我们解构我们的 发现 命令。 从最上层看,我们看到我们的测试被安排为两个分组,由一个 -要么 操作员:
( 表达式 1 ) -或者 ( 表达式 2 )
这是有道理的,因为我们正在搜索具有特定权限集的文件和具有不同权限集的目录。 如果我们正在寻找文件和目录,为什么
我们用 -要么 而不是 -和? 因为作为 发现 扫描文件和目录,评估每个文件和目录是否与指定的测试匹配。 我们想知道是不是 任何一个 具有错误权限的文件 or 权限不良的目录。 不可能两者同时存在。 所以如果我们展开分组表达式,我们可以这样看:
(具有错误权限的文件)-或(具有错误权限的目录)
我们的下一个挑战是如何测试“不良权限”。 我们怎么做? 其实我们没有。 我们将测试的是“不好的权限”,因为我们知道什么是“好的权限”。 对于文件,我们将良好定义为 0600,对于目录,定义为 0700。测试文件“不好”权限的表达式是:
-type f -和 -not -perms 0600
和目录:
-type d -and -not -perms 0700
如上表中的运算符所述, -和 运算符可以安全地删除,因为它默认是隐含的。 因此,如果我们将所有这些重新组合在一起,我们将得到最终命令:
查找 ~ ( -type f -not -perms 0600 ) -or ( -type d -not
-烫发 0700 )
然而,由于括号对 shell 有特殊意义,我们必须对它们进行转义以防止 shell 试图解释它们。 在每个字符前面加上一个反斜杠字符就可以解决问题。
理解逻辑运算符的另一个特性很重要。 假设我们有两个由逻辑运算符分隔的表达式:
表达式1 -操作员 表达式2
在所有情况下, 表达式1 将始终执行; 但是,运营商将确定是否
expr2 被执行。 这是它的工作原理:
表 17-5:查找 AND/OR 逻辑
结果 表达式1 | 操作者 | 表达式2 是... |
真 | -和 | 始终执行 |
假 | -和 | 从未表演过 |
真 | -要么 | 从未表演过 |
假 | -要么 | 始终执行 |
为什么会发生这种情况? 这样做是为了提高性能。 拿 -和, 例如。 我们知道表达式 表达式1 -和 表达式2 如果结果为真,则不能为真 表达式1 is
false,因此执行 expr2 毫无意义。 同样,如果我们有表达式 expr1 -要么 expr2 且 expr1 的结果为真,执行 expr2 没有意义, 我们已经知道表达式 expr1 -要么 expr2 是真的。
好的,所以它有助于它运行得更快。 为什么这很重要? 这很重要,因为我们可以依靠这种行为来控制操作的执行方式,我们很快就会看到。