Назад | Перейти на главную страницу

Могу ли я заставить `find` возвращать не-0, если не найдено подходящих файлов?

Даже когда /tmp не имеет файла с именем something, ища его с find вернет 0:

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

Как я могу получить ненулевой статус выхода, когда find ничего не находит?

find /tmp -name something | grep .

Статус возврата будет 0 когда что-то найдено, и ненулевое в противном случае.

РЕДАКТИРОВАТЬ: изменено с egrep '.*' к гораздо более простому grep ., так как результат тот же.

Самое простое решение, которое не печатает, но выходит из 0 при обнаружении результатов

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

Выход 0 с помощью find выполняется легко, а выход> 0 сложнее, потому что обычно это происходит только с ошибкой. Однако мы можем сделать это:

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

Я только что нашел этот вопрос, пытаясь найти способ решить проблему с Puppet (изменить разрешения для папок в каталоге, но не для самого каталога), похоже, это работает:

test -n "$(find /tmp -name something)"

Мой конкретный вариант использования таков:

test -n "$(find /home -mindepth 1 -maxdepth 1 -perm -711)"

Что приведет к выходу кода 1, если команда find не найдет файлов с необходимыми разрешениями.

Это невозможно. Find возвращает 0, если он успешно завершается, даже если он не нашел файл (что является правильным результатом. не указывает на ошибку, когда файл действительно не существует).

Процитировать справочную страницу find

СТАТУС ВЫХОДА

find завершает работу со статусом 0, если все файлы обработаны успешно, больше 0, если возникают ошибки. Это намеренно очень широкое описание, но если возвращаемое значение не равно нулю, вам не следует полагаться на правильность результатов поиска.

В зависимости от того, чего вы хотите достичь, вы можете попытаться найти -print имя файла и проверьте его результат:

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

Я считаю, что это наиболее лаконичный и прямой метод:

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

Вот небольшой сценарий, который я назвал 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 и разделите выходную переменную на нули, или вы можете просто добавить для нее оператор печати.

Это не только find который возвращает коды статуса выхода как ноль в случае успеха. В unix, какую бы команду вы ни выполняли, в случае успеха она возвращает нулевой статус выхода.