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

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, захватывает их вместе с выходными путями в выходном файле.

mklement0
источник
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

Matt
источник
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
sdaau
источник
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на в конце команды поиска.

Bunti
источник
Хорошая привязка к 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
viraptor
источник
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файл не доступен для записи)
wjordan
источник
Как вы относитесь к предложению 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, и отобразить его) .

simpleuser
источник
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; поиск

Ян ака uptech
источник
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 ...] [выражение]
Ядав