Как я могу исключить все сообщения " отказано в разрешении "из"найти"?
мне нужно скрыть все доступ запрещен сообщения:
find . > files_and_folders
я экспериментирую, когда такое сообщение возникает. Мне нужно собрать все папки и файлы, к которым не возникает.
можно ли направить уровни разрешений на ?
Как я могу скрыть ошибки в то же время?
18 ответов:
Примечание:
* Этот ответ, вероятно, идет глубже, чем гарантирует прецедент, иfind 2>/dev/null
может быть достаточно хорош во многих ситуациях. Он может по-прежнему представлять интерес для кросс-платформенной перспективы и для обсуждения некоторых передовых методов оболочки в интересах поиска решения, которое является как можно более надежным, даже если защищенные случаи могут быть в значительной степени гипотетическими.
* если ваша система настроена на шоу локализованный ошибка сообщения, передfind
вызовы сLC_ALL=C
(LC_ALL=C find ...
), чтобы убедиться, что английский язык сообщения сообщаются, так чтоgrep -v 'Permission denied'
работает, как задумано. Неизменно, однако, любые сообщения об ошибках, которые do вам отображается будет на английском языке.если раковина
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
) все строки (сfind
поток stderr команды), которые содержат фразуPermission denied
и выводит оставшиеся строки в stderr (>&2
).такой подход:
надежная:
grep
применяется только к сообщения об ошибках (а не к комбинации путей к файлам и сообщения об ошибках, потенциально приводящие к ложным срабатываниям), и сообщения об ошибках, отличные от запрещенных разрешений, передаются в stderr.без побочных эффектов:
find
код выхода сохраняется: невозможность доступа хотя бы к одному из элементов файловой системы приводит к коду выхода1
(хотя это не скажет вам, есть ли ошибки другое чем разрешение-отказано в них произошло (слишком.))
POSIX-совместимые решения:
полностью POSIX-совместимые решения либо имеют ограничения, либо требуют дополнительной работы.
если
find
выход должен быть захвачен в file в любом случае (или подавляется полностью), то решение на основе конвейера из ответ Джонатана Леффлера просто, робастно, и POSIX-уступчиво:find . 2>&1 >files_and_folders | grep -v 'Permission denied' >&2
отметим, что порядок перенаправления имеет значение:
2>&1
должны прийти первый.захват вывода stdout в файле спереди позволяет
2>&1
отправить только сообщения об ошибках через трубопровод, которыйgrep
может после этого однозначно работать дальше.The единственным недостатком является то, что общий выход код будет
grep
команды, а неfind
's, которое в данном случае означает: если есть нет ошибки вообще или только разрешение-отказано ошибки, код выхода будет1
(сигнализации провал), в противном случае (ошибки, отличные от запрещенных разрешений)0
- что является противоположностью намерения.
что сказал:find
код выхода редко используется в любом случае, как это часто передает мало информации за пределами фундаментальной сбой, такой как прохождение несуществующего пути.
Однако конкретный случай даже только некоторые из входных путей недоступны из-за отсутствия разрешений и отражены вfind
код выхода (как в GNU, так и в BSDfind
): если ошибка разрешения-отказано происходит для любой из обработанных файлов код выхода имеет значение1
.следующий вариант адресует это:
find . 2>&1 >files_and_folders | { grep -v 'Permission denied' >&2; [ $? -eq 1 ]; }
теперь код выхода указывает, есть ли ошибки кроме
Permission denied
произошли:1
если это так,0
в противном случае.
Другими словами: код выхода теперь отражает истинное намерение команды: success (0
) сообщается, если нет ошибок вообще или только разрешение-отказано ошибки произошли.
Это, возможно, даже лучше, чем просто прохождениеfind
' s код выхода через, как в решении в верхней части.
gniourf_gniourf в комментариях предлагает a (все еще 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
, а неfind
' s, но то же самое исправление, что и выше, может быть применено.
примечания по существующим ответы:
есть несколько моментов, чтобы отметить о ответ Майкла Брукса,
find . ! -readable -prune -o -print
:
требует GNU
find
; примечательно, что он не будет работать на macOS. Конечно, если вам нужна только команда для работы с GNUfind
, это не будет для вас проблемой.некоторые
Permission denied
ошибки еще поверхность:find ! -readable -prune
сообщает о таких ошибках для элемент ребенок элементы справочников, для которых текущий пользователь имеетr
разрешения, но не хватаетx
(исполняемый) разрешение. Причина в том, что сам каталог и читаемо,-prune
не выполняется, а попытка спуститься на этот каталог затем запускает сообщения об ошибках. Тем не менее,типичный дело поr
разрешение отсутствует.Примечание.: Следующий пункт является вопросом философии и / или конкретного случая использования, и вы можете решить, что это не относится к вам и что команда хорошо соответствует вашим потребностям, особенно если просто печати пути-это все, что вы делаете:
- если вы концептуализировать фильтрации разрешением опроверг сообщения об ошибках в отдельные задача, которую вы хотите иметь возможность применить к любой
find
команда, затем противоположный подход предварительно предупреждение ошибки с отказом в разрешении требуют введения "шума" вfind
команда, которая также вводит сложность и логический подводные камни.- например, самый популярный комментарий к ответу Майкла (на момент написания этой статьи) пытается показать, как расширения команда путем включения
-name
фильтра, следующим образом:find . ! -readable -prune -o -name '*.txt'
Это, однако, делает не работать по назначению, потому что трейлингпервое решение в ответ Джонатана Леффлера,
find . 2>/dev/null > files_and_folders
, как он сам заявляет, слепо молчанку все сообщения об ошибках (и решение является громоздким и не вполне надежным, так как он также объясняет). говоря прагматично, но это простое решение, поскольку вы можете быть довольны тем, что любые и все ошибки будут связаны с разрешением.туманный ответ,
sudo find . > files_and_folders
,лаконичен и прагматичен, но не рекомендуется ни для чего, кроме как просто печати имена, по соображениям безопасности: потому что вы работаете как root пользователь", вы рискуете иметь свой вся система была испорчена ошибкой в find или вредоносной версии, или неправильным вызовом, который пишет что-то неожиданно, что не могло произойти, если вы запустили это с обычными привилегиями" (из комментария к ответу mist by tripleee).2-е решение в viraptor ответ,
find . 2>&1 | grep -v 'Permission denied' > some_file
существует риск ложных срабатываний (из-за отправки смеси stdout и stderr по конвейеру), и, возможно, вместо этого из отчетности номера-ошибки с запрещенным разрешением через stderr, захватывает их вместе с выходными путями в выходном файле.
использование:
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
перенаправление ввода-вывода на - это:
2>&1 > files_and_folders |
. Труба перенаправляет стандартный вывод на и применяется в первую очередь. Элемент2>&1
отправляет стандартную ошибку в то же место, что и стандартный выход (труба). Элемент> files_and_folders
отправляет стандартный вывод (но не стандартную ошибку) в файл. Конечным результатом является то, что сообщения, записанные в стандартную ошибку, отправляются по трубе и регулярному выходуfind
записывается в файл. Элементgrep
фильтрует стандартный вывод (вы можете решить, насколько избирательным он должен быть, и, возможно, придется изменить орфографию в зависимости от локали и O/S) и окончательный>&2
означает, что оставшиеся сообщения об ошибках (записанные в стандартный вывод) снова переходят в стандартную ошибку. Окончательное перенаправление может рассматриваться как необязательное в терминале, но было бы очень хорошей идеей использовать его в скрипте, чтобы сообщения об ошибках появлялись при стандартной ошибке.есть бесконечные вариации на эту тема, в зависимости от того, что вы хотите сделать. Это будет работать на любом варианте Unix с любой производной оболочки Bourne (Bash, Korn,...) и любой POSIX-совместимой версией
find
.если вы хотите адаптироваться к конкретной версии
find
у вас есть в вашей системе, могут быть доступны альтернативные варианты. GNUfind
в частности, имеет множество опций, недоступных в других версиях-см. принятый в настоящее время ответ для одного такого набора опций.
использование:
find . ! -readable -prune -o -print
или вообще
find <paths> ! -readable -prune -o <other conditions like -name> -print
- чтобы избежать "отказано в доступе"
- и не подавляйте (другие) сообщения об ошибках
- и получить статус выхода 0 ("все файлы успешно обработаны")
работает с: find (GNU findutils) 4.4.2. Предыстория:
- The
-readable
тест соответствует читаемым файлам. Элемент!
оператор возвращает true, когда тест ложен. И! -readable
матчи не читаемые каталоги (и файлы).- The
-prune
действие не спускается в каталог.! -readable -prune
можно перевести на: если каталог не читается, не спускайтесь в него.- The
-readable
тест учитывает списки управления доступом и другие артефакты разрешений, которые-perm
тест игнорирует.см. также
find
(1) manpage для получения более подробной информации.
если вы хотите начать поиск с корня "/", вы, вероятно, увидите вывод чего-то вроде:
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 "invert", чтобы не видеть выходные строки, которые имеют пары слов "отказано в разрешении":
find /. -name 'toBeSearched.file' 2>&1 | grep -v 'Permission denied'
Я должен был использовать:
find / -name expect 2>/dev/null
указав имя того, что я хотел найти, а затем сообщив ему перенаправить все ошибки в /dev/null
ожидайте, что это местоположение ожидаемой программы, которую я искал.
вы также можете использовать
-perm
и-prune
предикаты, чтобы избежать спуска в нечитаемые каталоги (см. также Как удалить инструкции распечатки "отказано в разрешении" из программы поиска? - Unix & Linux Stack Exchange):find . -type d ! -perm -g+r,u+r,o+r -prune -o -print > files_and_folders
Стандартная ошибка перенаправления. Например, если вы используете bash на машине unix, вы можете перенаправить стандартную ошибку в /dev / null следующим образом:
find . 2>/dev/null >files_and_folders
в то время как выше подходы не касаются случая для 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.
эти ошибки выводятся на стандартный вывод ошибок (fd 2). Чтобы отфильтровать их, просто перенаправьте все ошибки в /dev / null:
find . 2>/dev/null > some_file
или сначала присоединиться к stderr и stdout, а затем grep из этих конкретных ошибок:
find . 2>&1 | grep -v 'Permission denied' > some_file
простой ответ:
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
(предотвратить спуск в) но все же-type
d
), что не (\!
) имеют как-readable
и-executable
разрешения, или (-o
)
-readable
и-executable
опции являются расширениями GNU, а не частью POSIX стандарт- может еще вернется '
Permission denied
' о ненормальных / поврежденных файлах (например, см. сообщить об ошибке воздействие на файловые системы, смонтированные в контейнере с помощьюlxcfs
надежный ответ, который работает с любым 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 locale С помощью переменные среды,3>&2 2>&1 1>&3
и3>&2 2>&1
дублирования файловых дескрипторов для передачи потока стандартных ошибок вgrep
и[ $? = 1 ]
использует[]
чтобы инвертировать код ошибки, возвращаемыйgrep
чтобы приблизиться к исходному поведениюfind
.
- также будет фильтровать любым
'Permission denied'
ошибки, связанные для вывода перенаправления (например, еслиfiles_and_folders
сам файл не доступен для записи)
избежать просто предупреждения об отказе в разрешении, скажите find игнорировать нечитаемые файлы, обрезая их из поиска. Добавьте выражение в качестве или к своей находке, например
find / \! -readable -prune -o -name '*.jbd' -ls
это в основном говорит (сопоставьте нечитаемый файл и вырежьте его из списка) или (совпадение имени, как *.jbd и показать его [с ls]). (Помните, что по умолчанию выражения являются and'D вместе, если вы не используете-or.) Вам нужно-Общ во втором выражении или же find может добавить действие по умолчанию, чтобы показать либо совпадение, которое также покажет вам все нечитаемые файлы.
но если вы ищете реальные файлы в своей системе, обычно нет причин искать в /dev, который имеет много файлов, поэтому вы должны добавить выражение, которое исключает этот каталог, например:
find / -mount \! -readable -prune -o -path /dev -prune -o -name '*.jbd' -ls
Так (матч нечитаемый файл и чернослив из списка) или (путь /dev и чернослив из списка) или файл(матч, как *.jbd и отображать его).
использовать
sudo find / -name file.txt
это глупо (потому что вы поднимаете поиск) и небезопасно, но гораздо короче писать.
ни один из приведенных выше ответов не работал для меня. Все, что я нахожу в Интернете, фокусируется на: скрыть ошибки. Ни один должным образом не обрабатывает процесс return-code / exit-code. Я использую команду find в сценариях bash, чтобы найти некоторые каталоги, а затем проверить их содержимое. Я оцениваю команду find success с помощью exit-code: нулевое значение работает, в противном случае происходит сбой.
The ответ выше by Michael 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
эта последовательность выражений терпит неудачу, когда доступ на чтение предоставлен, но нет доступа на выполнение.
после некоторого тестирования я понял, об этом и изменил мой скрипт решение для:
nice find / home* / - maxdepth 5-follow \
\ (типа Д -! \ (- readable-a-executable \) \) -чернослив \
-о \
\ (типа Д-а-читаемым -а-исполняемый -с -именем "${m_find_name}" \) -печатьключ здесь должен поместить "не верно" для комбинированного выражения:
has read access AND has execute access
в противном случае он не имеет полного доступа, что означает: обрезать его. Это оказалось работать для меня в одном сценарии, который предыдущие предложенные решения не удалось.
Я привожу ниже технические детали для вопросов в разделе "Комментарии". Я прошу прощения, если детали чрезмерны.
- ¿почему с помощью команды Ницца? У меня есть идея здесь. Изначально я думал, что было бы неплохо уменьшить приоритет процесса при просмотре всей файловой системы. Я понял, что это не имеет смысла для меня, так как мой скрипт ограничен несколькими каталогами. Я уменьшил-maxdepth до 3.
- ¿зачем искать в пределах /home*/? Это ей не актуально для данной темы. Я устанавливаю все приложения вручную с помощью компиляции исходного кода с непривилегированными пользователями (не root). Они устанавливаются в пределах "/ home". Я могу иметь несколько двоичных файлов и версий, живущих вместе. Мне нужно найти все каталоги,проверить и создать резервную копию в режиме master-slave. У меня может быть более одного "/home" (несколько дисков, работающих на выделенном сервере).
- ¿зачем использовать-follow? Пользователи могут создание символических ссылок на каталоги. Это зависит от полезности, мне нужно вести учет найденных абсолютных путей.
вы можете использовать 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
следует к магии
-=Для MacOS=-
сделать новую команду с помощью псевдонима: просто добавьте в~/.строке файл:
alias search='find / -name $file 2>/dev/null'
и в новом окне терминала можно назвать:
$ file=<filename or mask>; search
например:
$ file=etc; search
Если вы используете CSH или TCSH, вот решение:
( find . > files_and_folders ) >& /dev/null
Если вы хотите вывести на терминал:
( find . > /dev/tty ) >& /dev/null
однако, как описано в FAQ "csh-whynot", вы не должны использовать CSH.