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

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

find . > files_and_folders

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

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

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


person Léo Léopold Hertz 준영    schedule 17.04.2009    source источник


Ответы (19)


Примечание:
* Этот ответ, вероятно, идет глубже, чем того требует вариант использования, и 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> >(...)), по-видимому, игнорируется (в ksh 93u+).

    • grep -v 'Permission denied' filters out (-v) all lines (from the find command's stderr stream) that contain the phrase Permission denied and outputs the remaining lines to stderr (>&2).

Этот подход:

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

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


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

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

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

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

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

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

Единственным недостатком является то, что общим кодом выхода будет grep команда, а не find, что в данном случае означает: если ошибок нет при всех или только ошибках с отказом в разрешении код выхода будет 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) обобщение этого решения с использованием сложных перенаправлений , который работает даже при стандартной печати путей к файлам в stdout:

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

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

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

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


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

  • Следует отметить несколько моментов относительно ответа Майкла Брюкса, find . ! -readable -prune -o -print:

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

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

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

      • If you conceptualize the filtering of the permission-denied error messages a separate task that you want to be able to apply to any find command, then the opposite approach of proactively preventing permission-denied errors requires introducing "noise" into the find command, which also introduces complexity and logical pitfalls.
      • Например, самый популярный комментарий к ответу Майкла (на момент написания этой статьи) пытается показать, как расширить команду, включив фильтр -name следующим образом:
        find . ! -readable -prune -o -name '*.txt'
        Это однако не работает должным образом, поскольку завершающее действие -print является обязательным (объяснение можно найти в этот ответ). Такие тонкости могут привести к ошибкам.
  • Первое решение в ответе Джонатана Леффлера, find . 2>/dev/null > files_and_folders, как он сам заявляет, слепо заставляет всех сообщения об ошибках (и обходной путь громоздкий и не полностью надежный, как он также объясняет). С прагматической точки зрения, однако, это простейшее решение, поскольку вы можете быть довольны предположением, что любые и все ошибки будут связаны с разрешениями.

  • ответ тумана, sudo find . > files_and_folders, краток и прагматичен, но не рекомендуется для чего-либо, кроме простой печати имена файлов, по соображениям безопасности: поскольку вы работаете от имени пользователя root, "вы рискуете испортить всю вашу систему из-за ошибки в find или вредоносной версии. , или неправильный вызов, который пишет что-то неожиданно, чего не могло бы произойти, если бы вы запустили это с обычными привилегиями "(из комментария к ответу mist от Tripleee).

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

person mklement0    schedule 31.10.2016
comment
Небольшой вопрос: почему вы используете подстановку процесса, а не просто канал: find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2? - person gniourf_gniourf; 25.12.2016
comment
@ LéoLéopoldHertz 준영: Если вы не хотите выводить данные во внешний файл, просто сделайте больше сантехники: { find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1 - person gniourf_gniourf; 26.12.2016
comment
@ LéoLéopoldHertz 준영: Просто он совместим с POSIX. Подстановки процессов >(...) специфичны для Bash. - person gniourf_gniourf; 26.12.2016
comment
Я не уверен, что сохранение кода выхода find следует подчеркивать и рекламировать: код выхода find, как известно, бесполезен. Здесь очень вероятно, что оно будет отличным от нуля (и это бесполезно). - person gniourf_gniourf; 26.12.2016
comment
Почему это разумно просто по сравнению с поиском. ! -удобочитаемый ...? В нем используются команды подстановки процессов и группировки, что усложняет задачу и что, возможно, не требуется. Почему нужно использовать только POSIX-совместимые функции поиска, но одновременно использовать bash или zsh? С моей точки зрения, аргументом должна быть операционная система: GNU / Linux vs BSD vs macOS. Чем ваше решение лучше по сравнению с ответом Джонатана Лефферса? Добавлено гораздо больше сложности / гораздо больше текста для чтения без каких-либо существенных преимуществ. - person Michael Brux; 29.12.2016
comment
С моей точки зрения, проблема не заглушает все ошибки, связанные с отказом в разрешении, могут быть ошибкой переноса или ошибкой в ​​macOS или ошибкой в ​​базовой файловой системе, но это не общий аргумент против find. ! -читабельно .... Или не аргумент против этого в среде GNU / Linux. - person Michael Brux; 29.12.2016
comment
POSIX явно требует разрешения execute/search файлового режима для «поиска» каталога (получения inode содержащихся файлов). find делает это, чтобы спуститься в подкаталог (в дополнение к требованию read разрешения для перечисления файлов в каталоге). Это не «ошибка» или «ошибка переноса». - person wjordan; 30.12.2016
comment
Если оставить в стороне обсуждение среды GNU / Linux и POSIX, я не вижу, как добавление параметров командной строки к команде find «загрязняет», «скрывает реальное намерение» или «затрудняет расширение», особенно когда прямое сравнение с альтернативными решениями, включающими конвейеры, дополнительные утилиты, перенаправление потока ошибок и т. д. - person wjordan; 30.12.2016
comment
GNU find можно установить в macOS: brew install findutils. - person Henrique Gontijo; 02.03.2019
comment
TL; DR, найдите. -name myname 2 ›& 1 | grep -v Permission denied (когда вы не строите ракетный корабль, а пытаетесь найти файл) - person Rusty75; 09.06.2020

Использовать:

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

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

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

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

person Jonathan Leffler    schedule 17.04.2009
comment
Если вы похожи на меня, заметьте, что нехватка места важна! 2>/dev/null, без пробела! - person Nik; 25.10.2013
comment
2> - это единое целое без пробелов; между ним и именем файла может быть пробел. Аналогично с другими перенаправлениями, такими как 2>&1 (который перенаправляет стандартную ошибку в то же место, что и стандартный вывод) или 2>&-, который закрывает стандартную ошибку и т. Д. См. Перенаправления для получения оставшейся кровавой информации. (Приведенный выше код является общей оболочкой, подобной POSIX, не относящейся к bash.) - person Jonathan Leffler; 25.10.2013
comment
Мне пришлось использовать заглавную букву P, потому что мой терминал выводил это: найти. 2 ›& 1 | grep -v 'В доступе отказано' - person David Doria; 30.05.2014
comment
@DavidDoria вы можете использовать grep -i или (в этом случае) grep -vi, чтобы игнорировать регистр. - person AndriusZ; 12.08.2014
comment
Насколько это приемлемое решение? 1) Вы перенаправляете ВСЕ ошибки на dev / null 2) Вы фильтруете явную строку ошибки !! В зависимости от того, что это, как известно, нестабильно, а что, если бы ваш файл находился в каталоге с именем «доступ запрещен»? Ой! - person Gunchars; 10.11.2014
comment
@Gunchars: вопросы, которые вы поднимаете, охватываются ответом - или явная строка ошибки покрывается спецификацией вопроса. Первая команда отправляет все ошибки в /dev/null; второй нет. И в ответе упоминается предположение, что у вас нет файлов с именем permission denied. Итак, я не понимаю, против чего вы на самом деле возражаете. - person Jonathan Leffler; 10.11.2014
comment
Я возражаю против того, чтобы строки ошибок grepping изменяли вывод программы. Это будет работать большую часть времени, но простота - не лучшее решение (найти с химической завивкой ниже). Чтобы дать вам пример, почему это не будет работать в OSX, потому что ошибка - Permission denied. То же самое для любой другой системы, где есть даже незначительные различия в строке ошибки (кто-нибудь интернационализирует?) - person Gunchars; 10.11.2014
comment
Чтобы сделать grep более надежным, лучше использовать LANG=C grep, поскольку в противном случае сообщения будут различаться, и grep не будет им соответствовать. Все еще не так твердо, как ответ user3701456. - person Thomas W; 16.02.2016
comment
@ThomasW: Хороший замечание, но это команда find (а не grep), вы должны префикс LANG=C (или, немного более надежно, LC_ALL=C). - person mklement0; 01.11.2016

Использовать:

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) справочную страницу для получения более подробной информации.

person Michael Brux    schedule 11.08.2014
comment
Чем это лучше или хуже, чем ответ Джонатана? У обоих одинаковые выходы? - person Léo Léopold Hertz 준영; 11.08.2014
comment
различия уже упомянуты. если вы не понимаете, то, может быть, ответы для вас не имеют значения? STDOUT то же самое - STDERR отличается (с этим ответом вы получаете другие сообщения об ошибках) - $? отличается (0 успешен с этим ответом, когда не возникает других ошибок - всегда ›0 неуспешно при перенаправлении на dev / null) - может быть, кому-то нужен правильный $? в сценарии - person Michael Brux; 11.08.2014
comment
Думаю, это более изящное решение этой темы. Нравится успешный результат $ ?. - person xtr; 21.11.2014
comment
@Masi, самый очевидный недостаток - это ответ Джонатана (grep -v), который исключает имя файла, содержащее 'Permission denied' :) - person Fruit; 10.04.2015
comment
Я считаю уместным добавить здесь, что если вам нужно добавить какие-то другие критерии поиска, это следует сделать с помощью -o: find . ! -readable -prune -o -name '*.txt' - person tempestadept; 30.04.2015
comment
Обратите внимание, что POSIX find не включает -readable в качестве опции; также find для BSD и, следовательно, Mac OS X (я не уверен в других системах). Итак, если у вас есть GNU find, это прекрасно работает, но неясно, как это адаптировать, если вы не можете гарантировать, что в системе установлен GNU find. (Он будет нормально работать в Linux; он может работать или не работать в другом месте.) - person Jonathan Leffler; 27.06.2015
comment
find . ! -readable -prune -o -name '*.txt' похоже, не работает в Ubuntu 14.04 с использованием find 4.2.2. Кажется, что это -name. По какой-то странной причине я добился успеха с find . \( ! -readable -prune \) -o -name '*.txt' -print - person con-f-use; 15.01.2016
comment
@ con-f-use - у меня была такая же проблема, я обнаружил, что мне нужен только -print, а не сложные скобки. - person IBam; 03.03.2016
comment
Есть ли эквивалент игнорирования несуществующих путей? Например, если у меня есть find path1 path2 path3 -type f, я не хочу, чтобы find выдавал ошибку, даже если пути отсутствуют. В противном случае я должен заранее составить список путей, проверив, какие из них существуют, и отсутствие пути не является для меня условием ошибки. - person haridsv; 24.06.2016
comment
@ con-f-use См. дополнительное объяснение re: скобки и -print здесь: stackoverflow.com/questions/1489277/ - person DreadPirateShawn; 28.09.2016
comment
@haridsv: Нет: find неизменно жалуется на несуществующие пути input. Вам нужно будет использовать одно из решений, которое фильтрует вывод find stderr и отфильтровывает No such file or directory сообщения. - person mklement0; 30.12.2016
comment
@MichaelBrux: запоздалый ++; обсуждение ниже, мой ответ продолжился, и обновленная версия, надеюсь, более сбалансирована. Читаемый, но неисполняемый каталог. по-прежнему вызывая ошибки отказа в разрешении для его дочерних элементов, это не ошибка, в конце концов: поскольку сам каталог доступен для чтения, -prune не срабатывает, и доступ к дочерним элементам затем не выполняется (из-за отсутствия разрешений для исполняемых файлов в каталоге) . Однако, как уже говорилось, это экзотический случай. - person mklement0; 30.12.2016
comment
Может ли это быть дополнительно ограничено удалением каталогов, которые не являются исполняемыми в дополнение к нечитаемым? - person Andrew McKinlay; 17.01.2017
comment
@AndrewMcKinlay см. gnu.org/software/findutils/manual /html_mono/find.html#Mode-Bits GNU find поддерживает -исполняемый тест - person Michael Brux; 18.01.2017
comment
@ con-f-use ваша команда сработала, потому что вы добавили -print в конец. Это действовало на совпадения -name '*.txt'.. Когда вы добавляете -print к одному из предложений в -o (логическое ИЛИ), find знает, что вы хотите распечатать только эту часть. В противном случае, если по умолчанию будет печататься все, что найдет. И обнаружилась нечитаемая вещь, хотя и не читаемая. (... как хорошо описано в ссылке, опубликованной DreadPirateShawn, теперь, когда я обращаю внимание) - person Dan Pritts; 29.03.2017
comment
Возможно, вы хотите использовать ! -readable -prune -false для подавления нечитаемых каталогов (и не только предупреждения) - person Henning; 04.04.2017
comment
в качестве примечания, похоже, не работает в env cygwin / msys - person xenoterracide; 16.01.2018

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

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 "invert", чтобы не видеть строки вывода, в которых есть 'Permission denied' пары слов:

    find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
    
person Fatih Aksu    schedule 15.02.2012
comment
@scottmrogowski, за исключением того, что он не отвечает на вопрос ... 1. попросите системного администратора добавить вас в файл sudoers. 2. sudo find... - person Stephen; 16.07.2013
comment
именно то, что я искал! - person DankMasterDan; 20.06.2018

Пришлось использовать:

find / -name expect 2>/dev/null

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

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

person Jeremy    schedule 04.02.2012
comment
@Masi, команда в ответе не использует expect. Вместо этого expect - это просто имя файла, который эта команда попытается найти. - person Dhruv Kapoor; 10.02.2014
comment
Слепое перенаправление всего вывода stderr только для того, чтобы игнорировать один класс сообщений об ошибках, обычно является плохой идеей - вы потеряете все другие произвольные ошибки в процессе. - person Josip Rodin; 24.09.2015

Преобразуйте stderr в /dev/null, используя 2> / dev / null

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

person Matt    schedule 17.04.2009
comment
У меня это отлично работает даже на Mac OSX. Или даже find . -name '...' -print 2>/dev/null - person shadowsheep; 19.02.2018

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

find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
person sdaau    schedule 23.03.2014
comment
-perm -g+r,u+r,o+r просто сопоставляет файлы, для которых установлено разрешение r (чтение) для всех трех участников безопасности файла, что не имеет прямого отношения к тому, может ли текущий пользователь читать этот файл. или не. У него есть возможность как пропустить файлы, которые текущий пользователь может прочитать, так и сопоставить файлы, которые он не может. - person mklement0; 24.10.2016
comment
Я думаю, find . -type d ! \( -perm -u+r -o -perm -g+r -o -perm -o+r \) -prune -o -print было бы хорошим решением. - person Mattia72; 29.11.2016
comment
@ 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. См. Также: этот мой ответ. - person mklement0; 16.01.2017

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

find . 2>/dev/null >files_and_folders
person Jason Coco    schedule 17.04.2009

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

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 в конце команды find.

person Bunti    schedule 01.02.2016
comment
Хорошая привязка к OS X! Ответ Джонатана объясняет часть 2>/dev/null. Не могли бы вы объяснить часть -exec du -ch {} + 2>/dev/null | grep total$. - person Léo Léopold Hertz 준영; 02.02.2016
comment
@Masi Вы можете использовать любую команду с опцией -exec, чтобы предпринять дальнейшие действия с файлами или каталогами, найденными командой find. du -ch file_pattern вычисляет размер каждого файла, совпадающего с file_pattern, и последняя строка этого вывода представляет собой общую сумму всех файлов, соответствующих file_pattern. См. Страницу руководства для du. grep total просто фильтрует строку, извлекающую общую сумму (последняя строка). - person Bunti; 03.02.2016

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

find . 2>/dev/null > some_file

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

find . 2>&1 | grep -v 'Permission denied' > some_file
person viraptor    schedule 17.04.2009

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

find . > files_and_folders 2>&-

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

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

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

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

Передайте find дополнительные параметры, которые -prune < / a> (запретить спуск), но все еще -print любой каталог (_12 _ d), который не работает (_14 _) имеют как -readable, так и _ 16_ разрешений или ( -o) -print любой другой файл.

  • -readable и _ 20_ параметры являются расширениями 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 ] использует _ 32_, чтобы инвертировать код ошибки, возвращаемый grep, чтобы приблизиться к исходному поведению find.

  • Также будет фильтровать любые 'Permission denied' ошибки из-за перенаправления вывода (например, если сам файл files_and_folders недоступен для записи)
person wjordan    schedule 25.12.2016
comment
Как вы относитесь к предложению Жорди Феррана? - Можете сравнить свой ответ с ним? - person Léo Léopold Hertz 준영; 25.12.2016
comment
Этот сценарий оболочки ответа, как указано, не является универсальным (перечисляет только каталоги, соответствующие $ {m_find_name}), и содержит несколько параметров, не относящихся к вопросу (nice, / home *, -maxdepth 5, -follow). Этот ответ более кратко обращается к конкретной проблеме «фильтрации читаемых, но не исполняемых каталогов», оставаясь при этом универсальным. - person wjordan; 25.12.2016
comment
@wjordan: Спасибо. Я удалил свои комментарии, но один момент все еще актуален: решение на основе -perm не стоит представлять, потому что оно более фундаментально, чем предполагает цитата, делает что-то другое, чем предполагалось: это чисто тест, ориентированный на файл, относящийся к владельцу и группе файла, ни один из которых не имеет никаких гарантированных отношений с пользователем, вызывающим команду (см. этот мой ответ. Похоже, теперь ваше измененное решение GNU не улавливает ошибки отказа в разрешении, возникающие из файлов. - person mklement0; 25.12.2016
comment
Я не распознаю синтаксис, который вы используете (ни как GNU, ни как BSD), но позвольте мне проиллюстрировать свою точку зрения автономным примером: echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=r печатает file, потому что его бит чтения пользователя установлен, но он относится к nobody пользователь, а не текущий пользователь. Текущий пользователь не может прочитать этот файл; попробуйте cat file. - person mklement0; 26.12.2016
comment
@ mklement0 спасибо за обсуждение, мне удалось добиться поведения, которое вы описали в другом тесте (не знаю, что я сделал не так в первый раз), кажется, что -perm не работает для определения текущих разрешений пользователя. Удалена эта альтернатива из этого ответа. - person wjordan; 26.12.2016

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

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

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

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

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

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

person simpleuser    schedule 16.09.2014

использовать

sudo find / -name file.txt

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

person mist    schedule 16.12.2014
comment
Вы ищите здесь всю файловую систему, так что вы имеете в виду поднять поиск. Почему вы называете это небезопасным? Потому что он ищет всю файловую систему? - person Léo Léopold Hertz 준영; 16.12.2014
comment
Потому что sudo запускает команду find с правами root, что в принципе плохая идея. Нарушаются принципы сегрегации и минимальных привилегий. - person mist; 16.12.2014
comment
Повышение здесь - это привилегии до root с sudo. Вы рискуете, что вся ваша система будет испорчена ошибкой в ​​find или вредоносной версией, или неправильным вызовом, который пишет что-то неожиданно, чего не могло бы случиться, если бы вы запустили это с обычными привилегиями. - person tripleee; 07.12.2015

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

ответ, приведенный выше Автор Майкл Брюкс иногда работает. Но у меня есть один сценарий, в котором это не удается! Я обнаружил проблему и исправил ее сам. Мне нужно обрезать файлы, когда:

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 -follow \
\ (-type d -a ! \ (-readable -a -executable \) \) -prune \
-o \
\ (-type d -a -readable -a -executable -a -name "$ {m_find_name}" \) -print

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

has read access AND has execute access

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

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

  • ¿Почему приятно использовать команду? У меня возникла идея здесь. Сначала я подумал, что было бы неплохо снизить приоритет процесса при просмотре всей файловой системы. Я понял, что для меня это не имеет смысла, поскольку мой сценарий ограничен несколькими каталогами. Я уменьшил -maxdepth до 3.
  • ¿Зачем искать в / home * /? Это не имеет отношения к этой теме. Я устанавливаю все приложения вручную через компиляцию исходного кода с непривилегированными пользователями (не root). Они устанавливаются в "/ home". У меня может быть несколько двоичных файлов и версий, живущих вместе. Мне нужно найти все каталоги, проверить и создать резервную копию в режиме ведущий-ведомый. У меня может быть более одного «/ home» (несколько дисков, работающих на выделенном сервере).
  • ¿Зачем использовать -follow? Пользователи могут создавать символические ссылки на каталоги. Это зависит от полезности, мне нужно вести учет найденных абсолютных путей.
person Jordi Ferran    schedule 22.12.2016
comment
Спасибо за ответ и приятные наблюдения! Я открыл здесь награду, чтобы лучше просмотреть ваш ответ. Я думаю, что это хорошее открытие, которое не мешает доступу на чтение и выполнение. - - Не могли бы вы объяснить, почему вы используете nice и find $HOME -maxdepth 5 -follow ...? - person Léo Léopold Hertz 준영; 22.12.2016
comment
Сценарий оболочки, как указано, не является универсальным (перечисляет только каталоги, соответствующие ${m_find_name}), и содержит несколько параметров, не относящихся к вопросу (nice, /home*, -maxdepth 5, -follow). Я добавил ответ, в котором более кратко рассматривается конкретная проблема «фильтрации читаемых, но не исполняемых каталогов», оставаясь при этом универсальным. - person wjordan; 25.12.2016

Вы можете использовать команду 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

Должен к магии

person Leonardo Hermoso    schedule 27.12.2016

- = Для MacOS = -

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

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

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

$ file=<filename or mask>; search

Например:

$ file = etc; поиск

person Jan aka uptech    schedule 09.08.2017

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

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

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

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

Однако , как описано в часто задаваемых вопросах "csh-whynot", не следует использовать CSH.

person Kayle Sawyer    schedule 16.01.2018
comment
Я хочу grep все файлы txt и исключить скрытые файлы / каталог, опустить сообщение Permission denied для печати. Я использую оболочку csh. Я использовал приведенные ниже команды, и они не работают. -type f -iname .txt -not -path '* / \.' | egrep -v В разрешении отказано найти. -type f -iname .txt -not -path '* / \.' 2 ›/ dev / null Попадание ниже Ошибка. find: пути должны предшествовать выражению: 2 Использование: find [-H] [-L] [-P] [-Olevel] [-D help | tree | search | stat | rates | opt | exec] [path ...] [выражение] - person yadav; 11.05.2020

Просто используйте это для поиска файла в вашей системе.

find / -name YOUR_SEARCH_TERM 2>&1 | grep YOUR_SEARCH_TERM

Давайте не будем заниматься ненужным излишним проектированием, вы просто хотите найти свой файл, верно? то это команда, которая выведет список файлов для вас, если они присутствуют в доступной вам области.

person user1735921    schedule 25.06.2021

Минимальное решение - просто добавить флаг readable.

find . -name foo -readable

person Orun    schedule 08.07.2021