如果找不到匹配的文件,我可以使`find`返回非0吗?


46

即使/tmp没有名为的文件something,使用搜索find也会返回0:

  $ find /tmp -name something 
  $ echo $?
  0

什么都find找不到时如何获得非零退出状态?

Answers:


44

我相信这是您想要做的一线客:

find /tmp -name something | egrep '.*'

返回状态将0是找到内容时的返回状态,否则返回非零值。

如果您还需要捕获的输出以find进行进一步处理,那么Sven的答案就涵盖了这一点。


14
正则表达式*上的结尾egrep是完全多余的。由于您没有使用egrep正则表达式语法,因此纯老式grep可能要快几微秒。
三胞胎

我学会使用find ... | read
山姆

14

最简单的解决方案,不打印,但在找到结果时退出0

find /tmp -name something | grep -q "."

2
双引号在这里没有任何作用。
haridsv

尽管双引号不提供任何代码功能,但它们确实使读者更清楚地知道句点字符是正则表达式而不是目录。
Dharma Bellamkonda

13

退出0很容易找到,而退出> 0则更困难,因为这通常仅在发生错误时发生。但是,我们可以实现它:

if find -type f -exec false {} +
then
  echo 'nothing found'
else
  echo 'something found'
fi

2
据我所知,这是行不通的。的退出代码find似乎并不取决于-exec它运行的任何s 的退出代码。
克里斯(Chris)2007年

@Chris为我工作,还有4个人投票支持
Steven Penny

此解决方案的错误错误示例: 查找/ existing-starting-point /不存在-starting-point -name file-in-existing-starting-point -exec false {} +
Gerald Schade

2
这确实可以正常工作,并已记录在案(尽管隐藏在本exec节中,而不是在返回值下方)。它无法区分未找到和发现自身出错(例如,在不存在的起点上调用它时)。
TGR

如果您需要此功能-是的
Gerald Schade

7

在试图找到解决Puppet问题的方式时刚刚找到了这个问题(更改目录下文件夹的权限,但未更改目录本身),这似乎可行:

! test -z $(find /tmp -name something)

我的特定用例是这样的:

! test -z $(find /home -mindepth 1 -maxdepth 1 -perm -711)

如果find命令找不到具有所需权限的文件,它将退出代码1。


在Mac上,这里的一些解决方案(并非全部尝试)都无法使用。做到了。
亚历克斯·霍尔

5

这是不可能的。如果成功退出,即使找不到文件,Find也会返回0(这是正确的结果,当文件确实不存在时,它并不表示错误)。

引用查找手册页

退出状态

如果所有文件都已成功处理,则find会以状态0退出;如果发生错误,则大于0。这是故意的非常宽泛的描述,但是如果返回值不为零,则不应依赖find结果的正确性。

根据您要实现的目标,您可以尝试找到-print文件名并根据其输出进行测试:

#!/bin/bash
MYVAR=`find . -name "something" -print`
if [ -z "$MYVAR" ]; then
    echo "Notfound"
else
   echo $MYVAR
fi

这当然是可能的,尽管不如人们所希望的那样强大。
Ruslan '18

手册页组织不良;Ruslan所说的内容记录在exec/ execdir选项下(与一起使用+):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Tgr

1

我觉得这是最简洁直接的方法:

test `find /tmp/ -name something -print -quit 2>/dev/null`

2
在这种情况下,如果find出错,它将结果打印到/ dev / null,返回非零出口,然后通过test命令将其固定为0。
杰夫·弗兰

我不相信那是真的。请描述您的示例。如果出现错误并找到退出,则字符串将为空,并且测试将返回非零。
danorton 2013年

我不确定您的示例可能是什么,但是我不小心省略了-print -quit,这可能会解决您的问题。
danorton 2013年

也许其他赞成投票的人(大概出于相同的原因)可以提供相反的例子吗?
danorton

1
好的,您就是不喜欢我的风格。对于我的用例,发现的任何错误都可能是噪音,或者是非常严重的,以致它们将显示在其他位置。无论如何,此方法都能正确回答最终问题:“路径中是否存在具有给定名称的可访问文件”。错误将返回正确的答案“否”。如果我想找出原因,则可以添加更复杂的代码来回答最初未在此处提出的问题。
danorton

0

这是我叫的一个小脚本test.py。它改进了其他发布的方法,如果设置了一个,它将返回一个错误代码,如果find没有列出任何文件,它将另外设置一个:

from subprocess import Popen
import sys

p = Popen(['find'] + sys.argv)
out, err = p.communicate()
if p.returncode:
    sys.exit(p.returncode)
if not out:
    sys.exit(1)

这是命令行输出:

$ python test.py . -maxdepth 1 -name notthere
$ echo $?
1
$ find . -maxdepth 1 -name notthere
$ echo $?
0
$ find . -failedarg
find: unknown predicate `-failedarg'
$ echo $?
1

然后,对于find出错但找到文件的结果:

$ ls -lh
$ d---------  2 jeff users   6 Feb  6 11:49 noentry
$ find .
.
./noentry
find: `./noentry': Permission denied
$ echo $?
1
$ find . | egrep '.*'
.
./noentry
find: `./noentry': Permission denied
$ echo $?
0
python ../test.py 
../test.py
$ echo $?
1

然后,如果您想要文件列表,则可以使用-print 0传递给find且将out变量拆分为null的方法,也可以仅为其添加打印语句。


-1

find成功时,不仅返回退出状态代码为零。在UNIX中,无论执行什么命令,如果命令执行成功,它将返回退出状态为零。

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.