Примечание:
* Этот ответ, вероятно, идет глубже, чем оправдывает сценарий использования, и 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, захватывает их вместе с выходными путями в выходном файле.
find . 2>&1 > files_and_folders | grep -v 'Permission denied' >&2
:?{ find . 3>&2 2>&1 1>&3 | grep -v 'Permission denied' >&3; } 3>&2 2>&1
>(...)
являются специфичными для Bash.find
должно быть подчеркнуто и объявлено:find
код выхода, как известно, бесполезен. Здесь очень вероятно, что он будет ненулевым (и бесполезным).execute/search
разрешения в файловом режиме, чтобы «искать» каталог (извлекать иноды содержащихся файлов).find
делает это для того, чтобы спуститься в подкаталог (в дополнение к требованиюread
разрешения перечислить файлы в каталоге). Это не ошибка или ошибка переноса.Использование:
Permission denied
Конечно, это скрывает не только ошибки, но и все сообщения об ошибках.Если вы действительно хотите сохранить другие возможные ошибки, такие как слишком много переходов по символической ссылке, но не из-за отказа в разрешении, вам, вероятно, придется с лёгкостью предположить, что у вас не так много файлов с именем «отказано в разрешении» и попробуйте:
Если вы строго хотите отфильтровать только стандартную ошибку, вы можете использовать более сложную конструкцию:
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 имеет множество опций, недоступных в других версиях - см. Принятый в настоящее время ответ для одного такого набора опций.источник
2>/dev/null
без места!2>
единое целое без пробелов; между ним и именем файла может быть пробел. Аналогично с другими перенаправлениями, такими как2>&1
(который перенаправляет стандартную ошибку в то же место, где происходит стандартный вывод), или2>&-
который закрывает стандартную ошибку, и т. Д. См. Перенаправления для получения дополнительной информации о кровопролитии. (Приведенный выше код является общей оболочкой, похожей на POSIX, а не только для нееbash
.)Использование:
или в более общем плане
Работает с: find (GNU findutils) 4.4.2. Фон:
-readable
Тест соответствует читаемым файлам.!
Оператор возвращает истину, если тест является ложным. И! -readable
соответствует не читаемым каталогам (и файлам).-prune
Действие не спускается в каталог.! -readable -prune
можно перевести на: если каталог не читается, не спускайтесь в него.-readable
Тест учитывает списки контроля доступа и другие разрешения артефактов которые на-perm
тест игнорируемых.Смотрите также
find
(1) man-страницу для более подробной информации.источник
-o
:find . ! -readable -prune -o -name '*.txt'
find
не включает-readable
в качестве опции; также неfind
для BSD и, следовательно, Mac OS X (я не уверен насчет других систем). Таким образом, если у вас естьfind
гарантия GNU , это прекрасно работает, но не очевидно, как это адаптировать, если вы не можете гарантировать, что в системе установлен GNUfind
. (Это будет хорошо работать в Linux; может работать или не работать в другом месте.)find . ! -readable -prune -o -name '*.txt'
похоже, не работает на Ubuntu 14.04 с использованием find 4.2.2. Похоже, в ингоре-name
. По какой-то странной причине у меня есть успехfind . \( ! -readable -prune \) -o -name '*.txt' -print
Если вы хотите начать поиск с корня "/", вы, вероятно, увидите что-то вроде:
Это из-за разрешения. Чтобы решить это:
Вы можете использовать команду sudo:
Он спрашивает пароль суперпользователя, при вводе пароля вы увидите результат, который вы действительно хотите. Если у вас нет разрешения на использование команды sudo, что означает, что у вас нет пароля суперпользователя, сначала попросите системного администратора добавить вас в файл sudoers.
Вы можете использовать перенаправление стандартного вывода ошибок из (обычно дисплея / экрана) в какой-либо файл и избежать появления сообщений об ошибках на экране! перенаправить в специальный файл / dev / null:
Вы можете использовать перенаправление вывода стандартной ошибки с (обычно отображение / экран) на стандартный вывод (обычно отображение / экран), а затем направить команду grep с параметром -v «инвертировать», чтобы не видеть строки вывода с разрешением «Отказано в доступе» пары слов:
источник
sudo find...
Я должен был использовать:
указав имя того, что я хотел найти, а затем попросив перенаправить все ошибки в / dev / null
ожидать, что это место ожидаемой программы, которую я искал.
источник
expect
. Вместо этогоexpect
это просто имя файла, который эта команда попытается найти.Труба
stderr
с/dev/null
помощью 2> / Dev / нульfind . -name '...' 2>/dev/null
источник
find . -name '...' -print 2>/dev/null
Вы можете также использовать
-perm
и-prune
предикаты , чтобы избежать спуска в нечитаемые каталоги (смотрите также Как удалить «доступ запрещен» отпечатки заявление программы находит - Unix и Linux Stack Exchange? ):источник
-perm -g+r,u+r,o+r
просто совпадает с файлами, которые имеютr
права доступа (чтение) для всех 3 участников безопасности файла , что не имеет прямого отношения к тому, может ли текущий пользователь читать этот файл или нет. Он может одновременно пропустить файлы, которые может прочитать текущий пользователь, и сопоставить файлы, которые он не может.find . -type d ! \( -perm -u+r -o -perm -g+r -o -perm -o+r \) -prune -o -print
было бы хорошим решением.-readable
с-perm
- см мой предыдущий комментарий и рассмотрим следующий пример:echo 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=r
отпечаткиfile
, так как его пользователь прочитал бит установлен, но он относится кnobody
пользователя, а не текущего пользователя. Текущий пользователь не может прочитать этот файл; попробуйcat file
. Смотрите также: это мой ответ .Перенаправить стандартную ошибку. Например, если вы используете bash на машине с Unix, вы можете перенаправить стандартную ошибку в / dev / null следующим образом:
источник
Хотя вышеприведенные подходы не учитывают ситуацию для 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
на в конце команды поиска.источник
2>/dev/null
. Можете ли вы объяснить, часть-exec du -ch {} + 2>/dev/null | grep total$
.-exec
опцией, чтобы выполнить дальнейшие действия с файлами или каталогами, найденнымиfind
командой.du -ch file_pattern
вычисляет размер каждого совпадения файлов,file_pattern
и последняя строка этого вывода представляет собой общий итог всех файлов, которые соответствуютfile_pattern
. Смотрите справочную страницу дляdu
.grep total
просто фильтрует строку, которая извлекает общую сумму (которая является последней строкой).Эти ошибки выводятся на стандартный вывод ошибок (fd 2). Чтобы отфильтровать их, просто перенаправьте все ошибки в / dev / null:
или сначала объедините stderr и stdout, а затем найдите эти конкретные ошибки:
источник
Простой ответ:
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
любой каталог ( ), у которого нет ( ) обоих и прав, или ( ) любого другого файла.-type
d
\!
-readable
-executable
-o
-print
-readable
и-executable
опции являются расширениями GNU, а не частью стандарта POSIXPermission 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
файл не доступен для записи)источник
-perm
решение на основе не стоит представлять, потому что оно более фундаментально, чем предполагает цитата, делает нечто иное, чем предполагалось: это чисто файлово-ориентированный тест, относящийся к владельцу файла и group, ни один из которых не имеет каких-либо гарантированных отношений с пользователем, вызывающим команду (см. мой ответ . Похоже, что ваше пересмотренное решение GNU теперь неecho 'hi' > file; sudo chown nobody:nobody file; sudo chmod o-r file; find file -perm -u=r
печатаетfile
, потому что установлен бит чтения пользователя, но он относится кnobody
пользователю , а не текущий пользователь. Текущий пользователь не может прочитать этот файл; попробуйcat file
.-perm
оно не работает для определения текущих разрешений пользователя. Убрал эту альтернативу из этого ответа.Чтобы избежать только предупреждений об отказе в разрешении, скажите find игнорировать нечитаемые файлы, удаляя их из поиска. Добавьте выражение как ИЛИ в свою находку, например
В основном это говорит (сопоставить нечитаемый файл и удалить его из списка) ИЛИ (сопоставить имя, подобное * .jbd, и отобразить его [с помощью ls]) . (Помните, что по умолчанию выражения объединяются в AND, если только вы не используете -or.) Во втором выражении вам необходимо указать -ls, иначе команда find может добавить действие по умолчанию, чтобы показать совпадение, которое также покажет вам все нечитаемые файлы. ,
Но если вы ищете реальные файлы в вашей системе, обычно нет смысла искать в / dev, который имеет много файлов, поэтому вы должны добавить выражение, исключающее этот каталог, например:
Итак (сопоставить нечитаемый файл и удалить из списка) ИЛИ (сопоставить путь / dev и удалить из списка) ИЛИ (сопоставить файл, такой как * .jbd, и отобразить его) .
источник
использование
Это глупо (потому что вы повышаете уровень поиска) и небезопасно, но писать намного короче.
источник
sudo
. Вы рискуете, что вся ваша система будет испорчена ошибкойfind
или злонамеренной версией, или неправильным вызовом, который записывает что-то неожиданно, что не может произойти, если вы запустите это с обычными привилегиями.Ни один из приведенных выше ответов не работал для меня. Все, что я нахожу в Интернете, фокусируется на: скрыть ошибки. Никто правильно не обрабатывает код возврата процесса / код выхода. Я использую команду find в скриптах bash, чтобы найти некоторые каталоги, а затем проверить их содержимое. Я оцениваю команду найти успех, используя код выхода: нулевое значение работает, в противном случае происходит сбой.
Ответ Приведенный выше по Майкл Brux иногда работает. Но у меня есть один сценарий, в котором он терпит неудачу! Я обнаружил проблему и решил ее сам. Мне нужно удалить файлы, когда:
Смотрите ключевую проблему здесь: И / ИЛИ. Одна хорошая предложенная последовательность условий, которую я прочитал:
Это не всегда работает. Это означает, что обрезка срабатывает, когда совпадение:
Эта последовательность выражений завершается ошибкой, когда предоставляется доступ на чтение, но нет доступа на выполнение.
После некоторого тестирования я понял об этом и изменил свое решение сценария оболочки на:
Ключевым моментом здесь является размещение «не верно» для комбинированного выражения:
В противном случае он не имеет полного доступа, что означает: обрезать его. Это помогло мне в одном сценарии, в котором предыдущие предложенные решения потерпели неудачу.
Ниже приведены технические детали для вопросов в разделе комментариев. Я прошу прощения, если детали являются чрезмерными.
источник
nice
иfind $HOME -maxdepth 5 -follow ...
?${m_find_name}
), и содержит несколько вариантов , не имеющих отношения к данному вопросу (nice
,/home*
,-maxdepth 5
,-follow
). Я добавил ответ, который более конкретно решает проблему «фильтрации читаемых, но не исполняемых каталогов», оставаясь при этом универсальным.Вы можете использовать grep -v invert-match
нравится:
Следует магии
источник
- = Для MacOS = -
Создайте новую команду, используя псевдоним: просто добавьте в строку ~ / .bash_profile:
и в новом окне терминала вы можете вызвать его:
источник
Если вы используете CSH или TCSH, вот решение:
Если вы хотите вывод на терминал:
Однако, как описано в FAQ по csh-whynot, вы не должны использовать CSH.
источник