Чи можу я зробити `find` return non-0, коли не знайдено відповідних файлів?


46

Навіть коли /tmpфайл не викликається something, пошук при ньому findповерне 0:

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

Як я можу отримати ненульовий статус виходу, коли findнічого не знаходить?

Відповіді:


44

Ось однолінійний перехід, який я вважаю, робить те, що ви хочете:

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

Статус повернення буде, 0коли щось знайдено, а не нульове в іншому випадку.

Якщо вам також потрібно зафіксувати вихід findдля подальшої обробки, відповідь Свена охопила це.


14
Трейлінг *на egrepрегулярній виразці є абсолютно зайвим. Оскільки ви не використовуєте egrepсинтаксис регулярного вираження, звичайний старий grepможе пройти на кілька мікросекунд швидше.
tripleee

я навчився використовуватиfind ... | read
Сем

14

Найпростіше рішення, яке не друкується, але залишає 0, коли результати знайдені

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

2
Подвійні котирування тут не мають жодної мети.
haridsv

У той час як подвійні лапки не виконують жодної функції коду, вони роблять зрозумілішим для читача, що символ періоду - це регулярний вираз, а не каталог.
Дхарма Белламконда

13

Вихід 0 легко знайти, вихід> 0 складніше, оскільки це відбувається лише з помилкою. Однак ми можемо це зробити:

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

2
Наскільки я можу сказати, це не працює. Код виходу findначебто не залежить від кодів виходу будь-якого -execs, який він запустив.
Кріс

@Chris працює на мене, і 4, хто виступив з промовою
Стівен Пенні

приклад помилково помилкового результату цього рішення: знайти / існуючий-початковий пункт / неіснуючий-початковий пункт-ім'я файла-в-існуючий-початковий-точка -exec false {} +
Джеральд Шаде

2
Це працює правильно і задокументовано (хоча приховано в execрозділі, а не під зворотним значенням). Він не може розрізняти нічого, що знайдено, і виявляється, що помиляється (наприклад, коли його викликали на неіснуючій початковій точці).
Тгр

Якщо вам потрібна ця функціональність - так
Gerald Schade

7

Щойно знайшовши це питання, намагаючись знайти спосіб вирішити проблему з Лялькою (змінити дозволи для папок під каталогом, але не для самого каталогу), схоже, це працює:

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

Мій конкретний випадок використання:

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

Який вийде з коду 1, якщо команда find не знайде файлів із необхідними дозволами.


Кілька рішень (не випробував їх усіх) тут не працювали на Mac; це зробили.
Алекс Холл

5

Це неможливо. Знайдіть повернення 0, якщо воно закінчується успішно, навіть якщо він не знайшов файл (це правильний результат, який не вказує на помилку, коли файл дійсно не існує).

Процитуйте сторінку пошуку

ВИХОВИЙ СТАТУС

знайти виходи зі статусом 0, якщо всі файли обробляються успішно, більше 0, якщо трапляються помилки. Це навмисно дуже широкий опис, але якщо значення повернення не дорівнює нулю, не слід покладатися на правильність результатів пошуку.

Залежно від того, чого ви хочете досягти, ви можете спробувати дозволити знайти -printім'я файлу та перевірити його вихід:

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

Це, безумовно, можливо , хоча і не настільки надійно, як можна було б хотіти.
Руслан

Сторінка керівництва погано організована; те, що сказав Руслан, задокументовано під exec/ execdirопцією (використовується з +):If any invocation returns a non-zero value as exit status, then find returns a non-zero exit status.
Тгр

1

Я вважаю, що це найбільш стислий і прямий метод:

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

2
У цьому випадку, якщо у пошуку була помилка, вона надрукувала б результат / dev / null, поверне ненульовий вихід, а потім встановить тест за допомогою тестової команди 0.
Джефф Ферланд

Я не вірю, що це правда. Опишіть, будь ласка, свій приклад. Якщо виникла помилка і знайдете виходи, то рядок буде порожнім, а тест повернеться не нульовим.
данторн

Я не впевнений, яким може бути ваш приклад, але я випадково пропустив -print -quit, що може вирішити вашу проблему.
Данртон

Можливо, інша особа, яка прихильнилася (мабуть, з тієї ж причини), може надати протилежний приклад?
данторн

1
Гаразд, ти просто не любиш мій стиль. Для моїх випадків використання будь-які помилки, про які можна знайти, є або шумовими, або настільки серйозними, що відображатимуться в іншому місці. У будь-якому випадку цей метод правильно відповідає на остаточне запитання: "Чи є доступний файл у шляху за вказаним іменем". Помилка поверне правильну відповідь "Ні". Якщо я хочу з’ясувати, чому ні, я можу додати більш складний код, який відповідає на питання, які тут не ставились.
данторн

0

Ось невеликий сценарій, який я зателефонував test.py. Він покращує інші методи, розміщені в тому, що він поверне код помилки, якщо такий встановлений, і він додатково встановить його, якщо знахідка не перерахувала жодних файлів:

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та розділеною змінною на нулі, або ви можете просто додати до неї заяву друку.


-1

Він не тільки findповертає коди статусу виходу як нуль, коли він успішний. У unix, що коли-небудь команда, яку ви виконуєте, якщо її успішно, то вона повертає статус виходу як нуль.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.