Как я могу исключить все сообщения об отказе в разрешении из «поиска»?


797

Мне нужно скрыть все сообщения об отказе в разрешении от:

find . > files_and_folders

Я экспериментирую, когда возникает такое сообщение. Мне нужно собрать все папки и файлы, к которым он не возникает.

Можно ли направить уровни разрешений в files_and_foldersфайл?

Как я могу скрыть ошибки одновременно?

Ответы:


262

Примечание:
* Этот ответ, вероятно, идет глубже, чем оправдывает сценарий использования, и find 2>/dev/nullможет быть достаточно хорошим во многих ситуациях. Он может по-прежнему представлять интерес для кроссплатформенной перспективы и для обсуждения некоторых передовых методов оболочки в интересах поиска максимально надежного решения, даже если защищенные случаи могут быть в значительной степени гипотетическими.
* Если ваша система настроена на показ локализованных сообщений об ошибках , добавьте префиксы к findприведенным ниже вызовам LC_ALL=C( LC_ALL=C find ...), чтобы обеспечить сообщение на английском языке, чтобы все grep -v 'Permission denied'работало как задумано. Неизменно, однако, все сообщения об ошибках , которые действительно получают отображенные тогда будут на английском языке , а также.

Если ваша оболочка - это bashилиzsh , есть надежное, но достаточно простое решение , использующее только POSIX-совместимые findфункции ; хотя bashсам по себе он не является частью POSIX, большинство современных платформ Unix поставляются с ним, что делает это решение широко переносимым:

find . > files_and_folders 2> >(grep -v 'Permission denied' >&2)

Примечание. Существует небольшая вероятность того, что некоторые grepвыходные данные могут появиться после find завершения, потому что общая команда не ожидает завершения выполнения команды изнутри >(...). В bash, вы можете предотвратить это, добавив | catк команде.

  • >(...)является (редко используется) выходной процесс подстановки , который позволяет перенаправлять вывод (в данном случае, STDERR выход ( 2>) на стандартный ввод командного внутри >(...).
    Кроме того , bashи zsh, kshподдерживает их, а в принципе , но при попытке объединить их с переадресацией из stderr , как это делается здесь ( 2> >(...)), кажется, игнорируется (in ksh 93u+).

    • grep -v 'Permission denied'фильтры из ( -v) все линии (от findпотока Stderr командования) , которые содержат фразу Permission deniedи выводит оставшиеся строки в стандартный поток ошибок ( >&2).

Этот подход:

  • robust : grepприменяется только к сообщениям об ошибках (но не к комбинации путей к файлам и сообщений об ошибках, которые могут привести к ложным срабатываниям), а сообщения об ошибках, отличные от запрещенных, передаются в stderr.

  • Побочный эффект бесплатно : find«сек код выхода сохраняется: невозможность доступа по крайней мере один из элементов файловой системы , с которыми сталкиваются результаты в выходном коде 1(хотя это не о том , какой ошибки других произошло , чем разрешения, запрещённые (тоже)).


POSIX-совместимые решения:

Полностью POSIX-совместимые решения либо имеют ограничения, либо требуют дополнительной работы.

Если findвыход «S должен быть захвачен в файл в любом случае (или подавлена вообще), то трубопровод на основе решения от ответа Джонатана Леффлера является простым, надежным и POSIX-совместимый:

find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2

Обратите внимание, что порядок перенаправлений имеет значение: 2>&1должен идти первым .

Захват вывода stdout в файл с самого начала позволяет 2>&1отправлять только сообщения об ошибках по конвейеру, который grepзатем может однозначно работать.

Единственным недостатком является то, что общий код выхода будет grepкомандования , а не find«s, что в данном случае означает: если нет ни одной ошибки на всех или только ошибки разрешения, отказано, код выхода будет 1(сигнализации сбоя ), в противном случае ( ошибки, отличные от запрещенных разрешением), 0что противоречит намерению.
Тем не менее, findкод выхода в любом случае редко используется, так как он часто передает мало информации, кроме фундаментального сбоя, такого как прохождение несуществующего пути.
Тем не менее, конкретный случай даже только некоторыепути ввода, недоступные из-за отсутствия разрешений , отражаются в findкоде выхода России (как в GNU, так и в BSD find): если ошибка отказа в разрешении возникает для любого из обработанных файлов, для кода выхода устанавливается значение 1.

Следующая вариация адресована этим:

find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }

Теперь код выхода указывает, есть ли какие-либо ошибки, кроме Permission denied возникших: 1если так, то 0иначе.
Другими словами: код завершения теперь отражает истинное намерение команды: об успехе ( 0) сообщается, если вообще не было ошибок или только были отклонены разрешения.
Возможно, это даже лучше, чем просто пропускать findкод выхода, как в решении вверху.


В комментариях gniourf_gniourf предлагается (по-прежнему POSIX-совместимое) обобщение этого решения с использованием сложных перенаправлений , которое работает даже при стандартном поведении печати путей к файлу на стандартный вывод :

{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1

Вкратце: пользовательский дескриптор файла 3используется для временного обмена stdout ( 1) и stderr ( 2), так что только сообщения об ошибках могут передаваться grepчерез stdout.

Без этих перенаправлений и данные (пути к файлам), и сообщения об ошибках передавались бы grepчерез stdout, и grepтогда они не могли бы различить сообщение об ошибке Permission denied и (гипотетический) файл, имя которого содержит фразу Permission denied.

Однако, как и в первом решении, сообщается, что код выхода будет grep's, а не find', но можно применить то же исправление, что и выше.


Примечания к существующим ответам:

  • Есть несколько моментов , чтобы отметить о ответе Майкла Brux в , find . ! -readable -prune -o -print:

    • Требуется GNU find ; в частности, это не будет работать на macOS. Конечно, если вам когда-нибудь понадобится команда для работы с GNU find, это не будет проблемой для вас.

    • Некоторые Permission deniedошибки могут все еще появляться: find ! -readable -pruneсообщает о таких ошибках для дочерних элементов каталогов, для которых текущий пользователь имеет rразрешение, но не имеет x(исполняемого) разрешения. Причина заключается в том, что , поскольку сам каталог является читаемым, -pruneне выполняется, а попытка спуска в этот каталог , то вызывает сообщения об ошибках. Тем не менее, типичным случаем является отсутствие rразрешения.

    • Примечание. Следующий пункт является вопросом философии и / или конкретного случая использования, и вы можете решить, что он не относится к вам и что команда хорошо соответствует вашим потребностям, особенно если вы просто печатаете пути:

      • Если вы концептуализируете фильтрацию сообщений об ошибках с отказом в разрешении как отдельную задачу, которую вы хотите применить к любой find команде, тогда противоположный подход к профилактическому предотвращению ошибок с запрещенным разрешением требует введения в findкоманду «шума» , что также вводит сложность и логические подводные камни .
      • Например, наиболее одобренный комментарий к ответу Михаэля (на момент написания статьи) пытается показать, как расширить команду, добавив -nameфильтр, следующим образом:
        find . ! -readable -prune -o -name '*.txt'
        Это, однако, не работает должным образом, поскольку требуется завершающее -printдействие (объяснение можно найти в этом ответе ). Такие тонкости могут вносить ошибки.
  • Первое решение в ответе Джонатана Леффлера , find . 2>/dev/null > files_and_foldersкак он сам заявляет, вслепую заставляет замолчать все сообщения об ошибках (и обходной путь громоздок и не полностью надежен, как он также объясняет). С практической точки зрения , однако, это самое простое решение , так как вы можете согласиться с тем, что любые ошибки будут связаны с разрешениями.

  • Ответ Тумана , sudo find . > files_and_folders, является кратким и прагматичным, но опрометчивый для любых других целей, чем просто печать имен файлов , по соображениям безопасности: потому что вы работаете в качестве корневого пользователя « , вы рискуете имея всю систему будучи перепутались ошибкой в находке или вредоносная версия, или неправильный вызов, который пишет что-то неожиданно, что не может произойти, если вы запустили это с обычными привилегиями »(из комментария к ответу тумана от tripleee ).

  • Второе решение в ответ viraptor в , find . 2>&1 | grep -v 'Permission denied' > some_fileработает риск ложных срабатываний ( в связи с отправкой сочетание стандартный вывод и стандартный поток ошибок по трубопроводу), и, возможно, вместо того, чтобы сообщать не являющихся -permission-ошибки отказа через STDERR, захватывает их вместе с выходными путями в выходном файле.


4
Просто быстрый вопрос: почему вы используете подстановку процесса, а не просто канал find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2:?
— gniourf_gniourf

2
@ LéoLéopoldHertz 준영: Если вы не хотите выводить данные во внешний файл, просто сделайте больше сантехники:{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
— gniourf_gniourf

2
@ LéoLéopoldHertz 준영: Просто, что это POSIX-совместимый. Замены процесса >(...)являются специфичными для Bash.
— gniourf_gniourf

2
Я не уверен, что сохранение кода выхода findдолжно быть подчеркнуто и объявлено: findкод выхода, как известно, бесполезен. Здесь очень вероятно, что он будет ненулевым (и бесполезным).
— gniourf_gniourf

3
POSIX явно требует execute/searchразрешения в файловом режиме, чтобы «искать» каталог (извлекать иноды содержащихся файлов). findделает это для того, чтобы спуститься в подкаталог (в дополнение к требованию readразрешения перечислить файлы в каталоге). Это не ошибка или ошибка переноса.
— Вьордан

542

Использование:

find . 2>/dev/null > files_and_folders

Permission deniedКонечно, это скрывает не только ошибки, но и все сообщения об ошибках.

Если вы действительно хотите сохранить другие возможные ошибки, такие как слишком много переходов по символической ссылке, но не из-за отказа в разрешении, вам, вероятно, придется с лёгкостью предположить, что у вас не так много файлов с именем «отказано в разрешении» и попробуйте:

find . 2>&1 | grep -v 'Permission denied' > files_and_folders

Если вы строго хотите отфильтровать только стандартную ошибку, вы можете использовать более сложную конструкцию:

find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2

I / O Перенаправление на findкоманды: 2>&1 > files_and_folders |. Канал перенаправляет стандартный вывод в grepкоманду и применяется первым. 2>&1Отправляет стандартную ошибку в том же месте , что и стандартный вывод (трубы). > files_and_foldersПосылает стандартный вывод (но не стандартная ошибка) в файл. Конечным результатом является то, что сообщения, записанные со стандартной ошибкой, отправляются по конвейеру, а регулярный вывод findзаписывается в файл. grepФильтрует стандартный вывод (вы можете решить , как селективные вы хотите быть, и , возможно , придется изменить написание в зависимости от региона и O / S) и конечного>&2означает, что оставшиеся сообщения об ошибках (записанные в стандартный вывод) снова переходят к стандартной ошибке. Окончательное перенаправление может рассматриваться как необязательное в терминале, но было бы очень полезно использовать его в сценарии, чтобы сообщения об ошибках появлялись при стандартной ошибке.

Есть бесконечные вариации на эту тему, в зависимости от того, что вы хотите сделать. Это будет работать на любом варианте Unix с любым производным оболочки Bourne (Bash, Korn,…) и любой POSIX-совместимой версией find.

Если вы хотите адаптироваться к конкретной версии findвашей системы, могут быть доступны альтернативные варианты. findВ частности, GNU имеет множество опций, недоступных в других версиях - см. Принятый в настоящее время ответ для одного такого набора опций.


9
Если вы похожи на меня, обратите внимание, что нехватка места важна! 2>/dev/nullбез места!
— Ник

20
Это 2>единое целое без пробелов; между ним и именем файла может быть пробел. Аналогично с другими перенаправлениями, такими как 2>&1(который перенаправляет стандартную ошибку в то же место, где происходит стандартный вывод), или 2>&-который закрывает стандартную ошибку, и т. Д. См. Перенаправления для получения дополнительной информации о кровопролитии. (Приведенный выше код является общей оболочкой, похожей на POSIX, а не только для нее bash.)
— Джонатан Леффлер

3
Я должен был использовать заглавную букву P, потому что это то, что выводит мой терминал: найти. 2> & 1 | grep -v 'В доступе отказано'
— Дэвид Дория

4
Как это приемлемое решение? 1) Вы перенаправляете ВСЕ ошибки в dev / null 2) Вы фильтруете явную строку ошибок !! В зависимости от того, насколько они хрупки и что если ваш файл находится в каталоге с именем «отказано в доступе»? К сожалению!
— Gunchars

10
Я возражаю против смещения строк ошибок, чтобы изменить вывод программы. Это будет работать большую часть времени, но простое решение не является правильным (найдите с помощью perms ниже). Чтобы дать вам пример, почему это не будет работать в OSX, потому что ошибка «Отказано в доступе». То же самое для любой другой системы, где есть даже незначительные различия в строке ошибки (интернационализация кого-нибудь?)
— Gunchars

286

Использование:

find . ! -readable -prune -o -print

или в более общем плане

find <paths> ! -readable -prune -o <other conditions like -name> -print
  • чтобы избежать "В доступе отказано"
  • И НЕ подавлять (другие) сообщения об ошибках
  • И получить статус выхода 0 («все файлы успешно обработаны»)

Работает с: find (GNU findutils) 4.4.2. Фон:

  • -readableТест соответствует читаемым файлам. !Оператор возвращает истину, если тест является ложным. И ! -readableсоответствует не читаемым каталогам (и файлам).
  • -pruneДействие не спускается в каталог.
  • ! -readable -prune можно перевести на: если каталог не читается, не спускайтесь в него.
  • -readableТест учитывает списки контроля доступа и другие разрешения артефактов которые на -permтест игнорируемых.

Смотрите также find(1) man-страницу для более подробной информации.


6
различия уже упомянуты. если вы не понимаете, то, возможно, ответы не имеют никакого значения для вас? STDOUT то же самое - STDERR другое (вы получаете другие сообщения об ошибках с этим ответом) - $? отличается (0 «успешно» с этим ответом, когда нет другой ошибки - всегда> 0 «не успешно» при перенаправлении на dev / null) - может быть, кому-то нужно «исправить» $? в сценарии
— Майкл Брюкс

6
@Masi самый очевидный недостаток - ответ Джонатана (grep -v) исключит имя файла, содержащее «Отказано в доступе» :)
— Fruit

65
Я считаю уместным добавить здесь, что если вам нужно добавить некоторые другие критерии поиска, это должно быть сделано с помощью -o:find . ! -readable -prune -o -name '*.txt'
— tempestadept

22
Обратите внимание, что POSIX findне включает -readableв качестве опции; также не findдля BSD и, следовательно, Mac OS X (я не уверен насчет других систем). Таким образом, если у вас есть findгарантия GNU , это прекрасно работает, но не очевидно, как это адаптировать, если вы не можете гарантировать, что в системе установлен GNU find. (Это будет хорошо работать в Linux; может работать или не работать в другом месте.)
— Джонатан Леффлер,

6
find . ! -readable -prune -o -name '*.txt'похоже, не работает на Ubuntu 14.04 с использованием find 4.2.2. Похоже, в ингоре -name. По какой-то странной причине у меня есть успехfind . \( ! -readable -prune \) -o -name '*.txt' -print
— con-f-use

110

Если вы хотите начать поиск с корня "/", вы, вероятно, увидите что-то вроде:

find: /./proc/1731/fdinfo: Permission denied
find: /./proc/2032/task/2032/fd: Permission denied

Это из-за разрешения. Чтобы решить это:

  1. Вы можете использовать команду sudo:

    sudo find /. -name 'toBeSearched.file'

Он спрашивает пароль суперпользователя, при вводе пароля вы увидите результат, который вы действительно хотите. Если у вас нет разрешения на использование команды sudo, что означает, что у вас нет пароля суперпользователя, сначала попросите системного администратора добавить вас в файл sudoers.

  1. Вы можете использовать перенаправление стандартного вывода ошибок из (обычно дисплея / экрана) в какой-либо файл и избежать появления сообщений об ошибках на экране! перенаправить в специальный файл / dev / null:

    find /. -name 'toBeSearched.file' 2>/dev/null
  2. Вы можете использовать перенаправление вывода стандартной ошибки с (обычно отображение / экран) на стандартный вывод (обычно отображение / экран), а затем направить команду grep с параметром -v «инвертировать», чтобы не видеть строки вывода с разрешением «Отказано в доступе» пары слов:

    find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'

7
@scottmrogowski за исключением того, что он не отвечает на вопрос ... 1. попросите системного администратора добавить вас в файл sudoers. 2.sudo find...
— Стивен

1
именно то, что я искал!
— DankMasterDan

92

Я должен был использовать:

find / -name expect 2>/dev/null

указав имя того, что я хотел найти, а затем попросив перенаправить все ошибки в / dev / null

ожидать, что это место ожидаемой программы, которую я искал.


3
@Masi, команда в ответе не использует expect. Вместо этого expectэто просто имя файла, который эта команда попытается найти.
— Дхрув Капур

2
Слепое перенаправление всего вывода stderr просто для игнорирования одного класса сообщений об ошибках, как правило, плохая идея - вы потеряете все другие произвольные ошибки в процессе.
— Иосип Роден

60

Труба stderrс /dev/nullпомощью 2> / Dev / нуль

find . -name '...' 2>/dev/null


2
Это прекрасно работает даже на Mac OSX. Или дажеfind . -name '...' -print 2>/dev/null
— shadowsheep

30

Вы можете также использовать -permи -pruneпредикаты , чтобы избежать спуска в нечитаемые каталоги (смотрите также Как удалить «доступ запрещен» отпечатки заявление программы находит - Unix и Linux Stack Exchange? ):

find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders

4
-perm -g+r,u+r,o+rпросто совпадает с файлами, которые имеют rправа доступа (чтение) для всех 3 участников безопасности файла , что не имеет прямого отношения к тому, может ли текущий пользователь читать этот файл или нет. Он может одновременно пропустить файлы, которые может прочитать текущий пользователь, и сопоставить файлы, которые он не может.
— mklement0

Я думаю, что find . -type d ! \( -perm -u+r -o -perm -g+r -o -perm -o+r \) -prune -o -printбыло бы хорошим решением.
— Mattia72

2
@ Mattia72: Нет, это принципиально невозможно полностью эмулировать -readableс -perm- см мой предыдущий комментарий и рассмотрим следующий пример: echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=rотпечатки file, так как его пользователь прочитал бит установлен, но он относится к nobodyпользователя, а не текущего пользователя. Текущий пользователь не может прочитать этот файл; попробуй cat file. Смотрите также: это мой ответ .
— mklement0

23

Перенаправить стандартную ошибку. Например, если вы используете bash на машине с Unix, вы можете перенаправить стандартную ошибку в / dev / null следующим образом:

find . 2>/dev/null >files_and_folders

20

Хотя вышеприведенные подходы не учитывают ситуацию для Mac OS X, поскольку Mac Os X не поддерживает -readableпереключение, таким образом вы можете избежать ошибок «Отказано в доступе» в выходных данных. Это может помочь кому-то.

find / -type f -name "your_pattern" 2>/dev/null,

Если вы используете какую-то другую команду find, например, для определения размера файлов определенного шаблона в каталоге, 2>/dev/nullвсе равно будет работать, как показано ниже.

find . -type f -name "your_pattern" -exec du -ch {} + 2>/dev/null | grep total$,

Это вернет общий размер файлов данного шаблона. Обратите внимание 2>/dev/nullна в конце команды поиска.


Хорошая привязка к OS X! Ответ Джонатана объясняет роль 2>/dev/null. Можете ли вы объяснить, часть -exec du -ch {} + 2>/dev/null | grep total$.
— Лео Леопольд Герц 준영

1
@Masi Вы можете использовать любую команду с -execопцией, чтобы выполнить дальнейшие действия с файлами или каталогами, найденными findкомандой. du -ch file_patternвычисляет размер каждого совпадения файлов, file_patternи последняя строка этого вывода представляет собой общий итог всех файлов, которые соответствуют file_pattern. Смотрите справочную страницу для du. grep totalпросто фильтрует строку, которая извлекает общую сумму (которая является последней строкой).
— Бунти

13

Эти ошибки выводятся на стандартный вывод ошибок (fd 2). Чтобы отфильтровать их, просто перенаправьте все ошибки в / dev / null:

find . 2>/dev/null > some_file

или сначала объедините stderr и stdout, а затем найдите эти конкретные ошибки:

find . 2>&1 | grep -v 'Permission denied' > some_file

11

Простой ответ:

find . > files_and_folders 2>&-

2>&-closes ( -) стандартный дескриптор файла ошибок ( 2), поэтому все сообщения об ошибках отключаются.

  • Код выхода по-прежнему будет, 1если в Permission deniedпротивном случае будут напечатаны какие-либо ошибки

Надежный ответ для GNU find:

find . -type d \! \( -readable -executable \) -prune -print -o -print > files_and_folders

Передайте дополнительные параметры findэтому -prune(не допускайте спуска в), но все же -printлюбой каталог ( ), у которого нет ( ) обоих и прав, или ( ) любого другого файла.-typed\!-readable-executable-o-print

  • -readableи -executableопции являются расширениями GNU, а не частью стандарта POSIX
  • Может по-прежнему возвращать ' Permission denied' для ненормальных / поврежденных файлов (например, см. Отчет об ошибке, затрагивающий файловые системы, смонтированные в контейнере, с использованием lxcfs<v2.0.5)

Надежный ответ, который работает с любым POSIX-совместимым find(GNU, OSX / BSD и т. Д.)

{ LC_ALL=C find . 3>&2 2>&1 1>&3 > files_and_folders | grep -v 'Permission denied'; [ $? = 1 ]; } 3>&2 2>&1

Используйте конвейер, чтобы передать стандартный поток ошибок grep, удалив все строки, содержащие 'Permission denied'строку.

LC_ALL=Cустанавливает локаль POSIX с помощью переменной среды , 3>&2 2>&1 1>&3и 3>&2 2>&1 дублирующие файловые дескрипторы к трубе поток стандартного ошибка grep, и [ $? = 1 ]использует , []чтобы инвертировать код ошибки , возвращаемый grepаппроксимировать оригинальное поведение find.

  • Также будет фильтровать любые 'Permission denied'ошибки из-за перенаправления вывода (например, если сам files_and_foldersфайл не доступен для записи)

Как вы относитесь к предложению JordiFerran? - Можете ли вы сравнить свой ответ с этим?
— Лео Леопольд Герц 준영

2
Сценарий оболочки этого ответа, как указано, не является универсальным (только перечисляет каталоги, соответствующие $ {m_find_name}) и содержит несколько опций, не относящихся к вопросу (nice, / home *, -maxdepth 5, -follow). Этот ответ более конкретно решает проблему «фильтрации читаемых, но не исполняемых каталогов», оставаясь при этом универсальным.
— Вьордан

1
@wjordan: Спасибо. Я удалил свои комментарии, но один пункт все еще применим: -permрешение на основе не стоит представлять, потому что оно более фундаментально, чем предполагает цитата, делает нечто иное, чем предполагалось: это чисто файлово-ориентированный тест, относящийся к владельцу файла и group, ни один из которых не имеет каких-либо гарантированных отношений с пользователем, вызывающим команду (см. мой ответ . Похоже, что ваше пересмотренное решение GNU теперь не
— распознает

Я не распознаю синтаксис, который вы используете (ни как GNU, ни как BSD), но позвольте мне проиллюстрировать мою точку зрения на отдельном примере: echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=rпечатает file, потому что установлен бит чтения пользователя, но он относится к nobodyпользователю , а не текущий пользователь. Текущий пользователь не может прочитать этот файл; попробуй cat file.
— mklement0

1
@ mklement0 спасибо за обсуждение, мне удалось создать поведение, описанное вами в другом тесте (не знаю, что я сделал неправильно в первый раз), похоже, что -permоно не работает для определения текущих разрешений пользователя. Убрал эту альтернативу из этого ответа.
— Вьордан

4

Чтобы избежать только предупреждений об отказе в разрешении, скажите find игнорировать нечитаемые файлы, удаляя их из поиска. Добавьте выражение как ИЛИ в свою находку, например

find / \! -readable -prune -o -name '*.jbd' -ls

В основном это говорит (сопоставить нечитаемый файл и удалить его из списка) ИЛИ (сопоставить имя, подобное * .jbd, и отобразить его [с помощью ls]) . (Помните, что по умолчанию выражения объединяются в AND, если только вы не используете -or.) Во втором выражении вам необходимо указать -ls, иначе команда find может добавить действие по умолчанию, чтобы показать совпадение, которое также покажет вам все нечитаемые файлы. ,

Но если вы ищете реальные файлы в вашей системе, обычно нет смысла искать в / dev, который имеет много файлов, поэтому вы должны добавить выражение, исключающее этот каталог, например:

find / -mount \! -readable -prune  -o  -path /dev -prune  -o  -name '*.jbd' -ls

Итак (сопоставить нечитаемый файл и удалить из списка) ИЛИ (сопоставить путь / dev и удалить из списка) ИЛИ (сопоставить файл, такой как * .jbd, и отобразить его) .


4

использование

sudo find / -name file.txt

Это глупо (потому что вы повышаете уровень поиска) и небезопасно, но писать намного короче.


Вы ищете здесь всю файловую систему, так что вы подразумеваете под этим «повысить поиск». Почему вы называете это небезопасным? Потому что он ищет всю файловую систему?
— Лео Леопольд Герц 준영

2
Потому что sudo запускает команду find с правами root, что в принципе является плохой идеей. Принципы сегрегации и наименьших привилегий нарушаются.
— Туман

3
«Возвышение» здесь имеет привилегии, чтобы получить root права sudo. Вы рискуете, что вся ваша система будет испорчена ошибкой findили злонамеренной версией, или неправильным вызовом, который записывает что-то неожиданно, что не может произойти, если вы запустите это с обычными привилегиями.
— tripleee

2

Ни один из приведенных выше ответов не работал для меня. Все, что я нахожу в Интернете, фокусируется на: скрыть ошибки. Никто правильно не обрабатывает код возврата процесса / код выхода. Я использую команду find в скриптах bash, чтобы найти некоторые каталоги, а затем проверить их содержимое. Я оцениваю команду найти успех, используя код выхода: нулевое значение работает, в противном случае происходит сбой.

Ответ Приведенный выше по Майкл Brux иногда работает. Но у меня есть один сценарий, в котором он терпит неудачу! Я обнаружил проблему и решил ее сам. Мне нужно удалить файлы, когда:

it is a directory AND has no read access AND/OR has no execute access

Смотрите ключевую проблему здесь: И / ИЛИ. Одна хорошая предложенная последовательность условий, которую я прочитал:

-type d ! -readable ! -executable -prune

Это не всегда работает. Это означает, что обрезка срабатывает, когда совпадение:

it is directory AND no read access AND no execute access

Эта последовательность выражений завершается ошибкой, когда предоставляется доступ на чтение, но нет доступа на выполнение.

После некоторого тестирования я понял об этом и изменил свое решение сценария оболочки на:

хорошая находка / home * / -maxdepth 5 -исследовать \
    \ ( -тип d -a ! \ (-читабельный -a-исполняемый файл \) \) -prune \
    -o \
    \ (-тип d -a -читаемый -a - исполняемый файл -a -name "$ {m_find_name}" \) -print

Ключевым моментом здесь является размещение «не верно» для комбинированного выражения:

has read access AND has execute access

В противном случае он не имеет полного доступа, что означает: обрезать его. Это помогло мне в одном сценарии, в котором предыдущие предложенные решения потерпели неудачу.

Ниже приведены технические детали для вопросов в разделе комментариев. Я прошу прощения, если детали являются чрезмерными.

  • Using Почему с помощью команды приятно? У меня есть идея здесь . Сначала я подумал, что было бы неплохо уменьшить приоритет процесса при просмотре всей файловой системы. Я понял, что это не имеет смысла для меня, так как мой сценарий ограничен несколькими каталогами. Я уменьшил -maxdepth до 3.
  • Search Зачем искать в / home * /? Это не имеет отношения к этой теме. Я устанавливаю все приложения вручную через исходный код, скомпилированный с непривилегированными пользователями (не root). Они установлены в "/ home". Я могу иметь несколько двоичных файлов и версий, живущих вместе. Мне нужно найти все каталоги, проверить и сделать резервную копию в режиме «ведущий-ведомый». У меня может быть несколько «/ home» (несколько дисков, работающих на выделенном сервере).
  • Using Зачем использовать -follow? Пользователи могут создавать символические ссылки на каталоги. Это полезность зависит, мне нужно вести учет найденных абсолютных путей.

Спасибо за ваш ответ и приятные наблюдения! Я открыл щедрость здесь, чтобы лучше просмотреть ваш ответ. Я думаю, что это хорошая находка, не препятствующая доступу для чтения и выполнения. - - Не могли бы вы объяснить, почему вы используете niceи find $HOME -maxdepth 5 -follow ...?
— Лео Леопольд Герц 준영

2
Сценарий оболочки , как указано не общее назначение (только списки каталоги соответствие ${m_find_name}), и содержит несколько вариантов , не имеющих отношения к данному вопросу ( nice, /home*, -maxdepth 5, -follow). Я добавил ответ, который более конкретно решает проблему «фильтрации читаемых, но не исполняемых каталогов», оставаясь при этом универсальным.
— Вьордан

2

Вы можете использовать grep -v invert-match

-v, --invert-match        select non-matching lines

нравится:

find . > files_and_folders
cat files_and_folders | grep -v "permission denied" > files_and_folders

Следует магии


2

- = Для MacOS = -

Создайте новую команду, используя псевдоним: просто добавьте в строку ~ / .bash_profile:

alias search='find / -name $file 2>/dev/null'

и в новом окне терминала вы можете вызвать его:

$ file=<filename or mask>; search

например:

$ file = etc; поиск


1

Если вы используете CSH или TCSH, вот решение:

( find . > files_and_folders ) >& /dev/null

Если вы хотите вывод на терминал:

( find . > /dev/tty ) >& /dev/null

Однако, как описано в FAQ по csh-whynot, вы не должны использовать CSH.


Я хочу выполнить grep для всех текстовых файлов и исключить скрытые файлы / каталог, пропустить сообщение «Permission denied» для печати. Я использую оболочку csh. Я использовал ниже команды, и они не работают найти. -type f -имя " .txt" -not -path '* / \. '| egrep -v "В доступе отказано" найти. -type f -имя " .txt" -not -path '* / \. '2> / dev / null Ошибка ниже. find: пути должны предшествовать выражению: 2 Использование: find [-H] [-L] [-P] [-Olevel] [-D help | дерево | поиск | stat | rate | opt | exec] [path ...] [выражение]
— Ядав
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.