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

Мне нужно скрыть все отклоненные отклонения от сообщений:

find . > files_and_folders

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

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

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

Ответ 1

Примечание:
* Этот ответ, вероятно, идет глубже, чем ордера на использование, и 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>) в stdin команды внутри >(...).
    В дополнение к bash и zsh, ksh также поддерживает их в принципе, но попытка объединить их с перенаправлением из stderr, как это делается здесь (2> >(...)), кажется молча игнорируемой (в ksh 93u+).

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

Этот подход:

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

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


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

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

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

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

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

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

Единственным недостатком является то, что общий код выхода будет <<2 → 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 exit, как в решении вверху.


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 через stdout, а grep не сможет отличить сообщение об ошибке Permission denied и (гипотетический) файл, имя содержит фразу Permission denied.

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


Заметки по существующим ответам:

  • Есть несколько моментов, чтобы отметить ответ Майкла Брукса, 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, как он сам утверждает, слепо молчает все сообщения об ошибках ( и обходной путь является громоздким и не полностью надежным, как он объясняет). Прагматично говоря, однако, это простейшее решение, так как вы можете быть довольным предположить, что любые и все ошибки будут связаны с разрешением.

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

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

Ответ 2

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

find . 2>/dev/null > files_and_folders

Это скрывает не только разрешение, допускающее ошибки, но все сообщения об ошибках.

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

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 означает, что оставшиеся сообщения об ошибках (записанные на стандартный выход) еще раз перейдите к стандартной ошибке. Окончательное перенаправление можно рассматривать как необязательное на терминале, но было бы очень неплохо использовать его в script, чтобы сообщения об ошибках отображались при стандартной ошибке.

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

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

Ответ 3

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

find . ! -readable -prune -o -print

или в целом

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

Работает с: find (GNU findutils) 4.4.2. Справочная информация:

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

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

Ответ 4

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

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

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

  • Вы можете использовать команду sudo: sudo find /. -name 'toBeSearched.file'. он запрашивает пароль суперпользователя, когда вы вводите пароль, вы увидите результат, который вы действительно хотите.

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

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

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

Ответ 5

Мне пришлось использовать:

find / -name expect 2>/dev/null

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

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

Ответ 6

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

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

Ответ 8

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

find . 2>/dev/null >files_and_folders

Ответ 9

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

Ответ 10

Эти ошибки выводятся на стандартный вывод ошибки (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>&- закрывает (-) стандартный дескриптор файла ошибки (2), поэтому все сообщения об ошибках отключены.

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

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

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

Передайте дополнительные опции find, которые -prune (не спускайтесь), но -print любой каталог (-type d), который не (\!) имеют -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 не доступен для записи)

Ответ 12

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

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

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

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

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

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

Ответ 13

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

sudo find / -name file.txt

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

Ответ 14

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

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

Ответ 15

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

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

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

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

-type d ! -readable ! -executable -prune

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

it is directory AND no read access AND no execute access

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

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

nice find/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

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

Ниже приводятся технические детали для вопросов в разделе комментариев. Приносим извинения, если детали чрезмерны.

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

Ответ 16

- = Для MacOS = -

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

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

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

$ file=<filename or mask>; search

например:

$file = etc; поиск

Ответ 17

Вы также можете легко найти результаты поиска в файле.

найти. -name 'NameOfSearchedFile' → results.txt